kni.c代码2000+行,分解为kni_entry.c,kni_comm.c,kni_connect.c,kni_repair.c;
This commit is contained in:
9
Makefile
9
Makefile
@@ -1,7 +1,6 @@
|
||||
#CC = gcc
|
||||
CC = g++
|
||||
CFLAGS = -g -Wall -fPIC -shared
|
||||
OBJECTS = kni.o libforge_socket.o
|
||||
OBJECTS = kni_entry.o kni_comm.o kni_connect.o kni_repair.o
|
||||
TARGET = kni.so
|
||||
|
||||
INCS = -I./inc
|
||||
@@ -21,8 +20,10 @@ $(TARGET):$(OBJECTS)
|
||||
$(CC) -o $(TARGET) $(CFLAGS) $(OBJECTS) $(MODULES) $(LD_DICTATOR)
|
||||
# $(CC) -o $(TARGET) $(CFLAGS) $(OBJECTS) $(MODULES) -Wl,--whole-archive $(WHOLE_MODULES) -wL,--NO-WHOLE-ARCHIVE $(LD_DICTATOR)
|
||||
|
||||
kni.o:kni.c
|
||||
libforge_socket.o:libforge_socket.c
|
||||
kni_entry.o:kni_entry.c
|
||||
kni_comm.o:kni_comm.c
|
||||
kni_connect.o:kni_connect.c
|
||||
kni_repair.o:kni_repair.c
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJECTS)
|
||||
|
||||
358
kni_comm.c
Normal file
358
kni_comm.c
Normal file
@@ -0,0 +1,358 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "stream.h"
|
||||
#include "MESA_prof_load.h"
|
||||
#include "MESA_handle_logger.h"
|
||||
#include "field_stat2.h"
|
||||
#include "kni_entry.h"
|
||||
#include "kni_comm.h"
|
||||
|
||||
|
||||
|
||||
const char *g_kni_fs2_name[FS2_COLUMN_NUM] ={"RECV_PKTS","WRITE_PKTS","READ_PKTS","SEND_PKTS","BMD_IP","BMD_DOMAIN","HTTP_PKTS","SSL_PKTS","DROP_PKTS"};
|
||||
|
||||
|
||||
int kni_log_info_v4(char* module,struct stream_tuple4_v4* addr,unsigned short protocol,char* domain,char* scan_result,char* action)
|
||||
{
|
||||
unsigned short sport=0;
|
||||
unsigned short dport=0;
|
||||
char saddr_v4[INET_ADDRSTRLEN]={0};
|
||||
char daddr_v4[INET_ADDRSTRLEN]={0};
|
||||
|
||||
sport=ntohs(addr->source);
|
||||
dport=ntohs(addr->dest);
|
||||
inet_ntop(AF_INET, (void *)&(addr->saddr), saddr_v4, INET_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET, (void *)&(addr->daddr), daddr_v4, INET_ADDRSTRLEN);
|
||||
|
||||
if(protocol==KNI_FLAG_HTTP)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,module,"addr:%s,%d,%s,%d,%s,domain:%s,%s,%s",saddr_v4,sport,daddr_v4,dport,"HTTP",domain,scan_result,action);
|
||||
}
|
||||
else if(protocol==KNI_FLAG_SSL)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,module,"addr:%s,%d,%s,%d,%s,domain:%s,%s,%s",saddr_v4,sport,daddr_v4,dport,"SSL",domain+5,scan_result,action);
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,module,"addr:%s,%d,%s,%d,domain:%s,%s,%s",saddr_v4,sport,daddr_v4,dport,domain,scan_result,action);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int kni_log_debug_v4(int level,char* module,struct ip* a_packet,char* content)
|
||||
{
|
||||
|
||||
struct tcphdr* tcphdr=(struct tcphdr*)((char*)a_packet+4*(a_packet->ip_hl));
|
||||
|
||||
unsigned short sport=0;
|
||||
unsigned short dport=0;
|
||||
char saddr_v4[INET_ADDRSTRLEN]={0};
|
||||
char daddr_v4[INET_ADDRSTRLEN]={0};
|
||||
|
||||
sport=ntohs(tcphdr->source);
|
||||
dport=ntohs(tcphdr->dest);
|
||||
inet_ntop(AF_INET, (void *)&((a_packet->ip_src).s_addr), saddr_v4, INET_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET, (void *)&((a_packet->ip_dst).s_addr), daddr_v4, INET_ADDRSTRLEN);
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,level,module,"addr:%s,%d,%s,%d %s",saddr_v4,sport,daddr_v4,dport,content);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
if(sport<dport) server=s
|
||||
else if((sport==dport)&&(sip<dip)) server=s
|
||||
else server=d
|
||||
****************************************************************************/
|
||||
int kni_get_ipaddr_v4(void* a_packet,struct stream_tuple4_v4* ipaddr)
|
||||
{
|
||||
int reverse_flag=0;
|
||||
|
||||
unsigned short sport=0;
|
||||
unsigned short dport =0;
|
||||
|
||||
struct ip* iphdr=(struct ip*)a_packet;
|
||||
struct tcphdr* tcphdr=NULL;
|
||||
|
||||
iphdr=(struct ip*)a_packet;
|
||||
tcphdr=(struct tcphdr*)((char*)iphdr+4*(iphdr->ip_hl));
|
||||
|
||||
sport=ntohs(tcphdr->source);
|
||||
dport=ntohs(tcphdr->dest);
|
||||
|
||||
if((sport<dport)||((sport==dport)&&(ntohl((iphdr->ip_src).s_addr)<ntohl((iphdr->ip_dst).s_addr))))
|
||||
{
|
||||
reverse_flag=1;
|
||||
}
|
||||
|
||||
if(reverse_flag==1)
|
||||
{
|
||||
ipaddr->saddr=(iphdr->ip_dst).s_addr;
|
||||
ipaddr->daddr=(iphdr->ip_src).s_addr;
|
||||
ipaddr->source=tcphdr->dest;
|
||||
ipaddr->dest=tcphdr->source;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipaddr->saddr=(iphdr->ip_src).s_addr;
|
||||
ipaddr->daddr=(iphdr->ip_dst).s_addr;
|
||||
ipaddr->source=tcphdr->source;
|
||||
ipaddr->dest=tcphdr->dest;
|
||||
}
|
||||
|
||||
|
||||
return reverse_flag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
if(sport<dport) server=s
|
||||
else if((sport==dport)&&(sip<dip)) server=s
|
||||
else server=d
|
||||
****************************************************************************/
|
||||
int kni_get_ipaddr_v6(void* a_packet,struct stream_tuple4_v6* ipaddr)
|
||||
{
|
||||
int reverse_flag=0;
|
||||
|
||||
unsigned short sport=0;
|
||||
unsigned short dport =0;
|
||||
|
||||
struct kni_ipv6_hdr* ipv6_hdr=(struct kni_ipv6_hdr*)a_packet;
|
||||
struct tcphdr* tcphdr=(struct tcphdr*)(unsigned char*)a_packet+sizeof(struct kni_ipv6_hdr);
|
||||
|
||||
sport=ntohs(tcphdr->source);
|
||||
dport=ntohs(tcphdr->dest);
|
||||
|
||||
if(sport<dport)
|
||||
{
|
||||
reverse_flag=1;
|
||||
}
|
||||
|
||||
if(reverse_flag==1)
|
||||
{
|
||||
memcpy(ipaddr->saddr,ipv6_hdr->ip6_dst.s6_addr32,IPV6_ADDR_LEN);
|
||||
memcpy(ipaddr->daddr,ipv6_hdr->ip6_src.s6_addr32,IPV6_ADDR_LEN);
|
||||
ipaddr->source=tcphdr->dest;
|
||||
ipaddr->dest=tcphdr->source;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(ipaddr->saddr,ipv6_hdr->ip6_src.s6_addr32,IPV6_ADDR_LEN);
|
||||
memcpy(ipaddr->daddr,ipv6_hdr->ip6_dst.s6_addr32,IPV6_ADDR_LEN);
|
||||
ipaddr->source=tcphdr->source;
|
||||
ipaddr->dest=tcphdr->dest;
|
||||
}
|
||||
|
||||
|
||||
return reverse_flag;
|
||||
}
|
||||
|
||||
int kni_get_tcpinfo(struct kni_wndpro_reply_info* lastpkt_info,struct kni_tcp_hdr* tcphdr,int tcplen,struct ip* ip_hdr)
|
||||
{
|
||||
lastpkt_info->seq=ntohl(tcphdr->th_seq);
|
||||
lastpkt_info->ack=ntohl(tcphdr->th_ack);
|
||||
lastpkt_info->ipid=ntohs(ip_hdr->ip_id);
|
||||
lastpkt_info->ttl=ip_hdr->ip_ttl;
|
||||
lastpkt_info->len=tcplen;
|
||||
lastpkt_info->wndsize=ntohs(tcphdr->th_win);
|
||||
|
||||
if(tcphdr->th_flags&TH_SYN)
|
||||
{
|
||||
lastpkt_info->syn_flag=1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,unsigned short* mss,unsigned char* winscale,unsigned char* scak,unsigned char* timestamps)
|
||||
{
|
||||
|
||||
*mss=KNI_DEFAULT_MSS;
|
||||
*winscale=KNI_DEFAULT_WINSCLE;
|
||||
|
||||
|
||||
int remain_len=tcp_hdr_len;
|
||||
struct kni_tcp_opt_format* tcp_opt=NULL;
|
||||
|
||||
if((tcp_hdr_len<=20)||(tcp_hdr_len>64))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcp_opt=(struct kni_tcp_opt_format*)((char*)tcphdr+TCPHDR_DEFAULT_LEN);
|
||||
remain_len-=TCPHDR_DEFAULT_LEN;
|
||||
|
||||
while(remain_len)
|
||||
{
|
||||
if(tcp_opt->type==KNI_TCPOPT_MSS) //MSS
|
||||
{
|
||||
remain_len-=tcp_opt->len;
|
||||
*mss=htons(*(unsigned short*)(tcp_opt->content));
|
||||
tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len);
|
||||
|
||||
continue;
|
||||
}
|
||||
else if(tcp_opt->type==KNI_TCPOPT_WINSCALE) //winscale
|
||||
{
|
||||
remain_len-=tcp_opt->len;
|
||||
*winscale=*(unsigned char*)(tcp_opt->content);
|
||||
tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len);
|
||||
|
||||
continue;
|
||||
}
|
||||
else if(tcp_opt->type==KNI_TCPOPT_SACKOK) //scak
|
||||
{
|
||||
remain_len-=tcp_opt->len;
|
||||
*scak=1;
|
||||
tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len);
|
||||
|
||||
continue;
|
||||
}
|
||||
else if(tcp_opt->type==KNI_TCPOPT_TIMESTAMP) //timestamp
|
||||
{
|
||||
remain_len-=tcp_opt->len;
|
||||
*timestamps=1;
|
||||
tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len);
|
||||
|
||||
continue;
|
||||
}
|
||||
else if((tcp_opt->type==0)||(tcp_opt->type==1))
|
||||
{
|
||||
remain_len-=1;
|
||||
tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+1);
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
remain_len-=tcp_opt->len;
|
||||
tcp_opt=(struct kni_tcp_opt_format*)((char*)tcp_opt+tcp_opt->len);
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
char* kni_get_data(const struct streaminfo* pstream,int* datalen)
|
||||
{
|
||||
char* data=NULL;
|
||||
|
||||
if(pstream->type==STREAM_TYPE_TCP)
|
||||
{
|
||||
data=(char*)(pstream->ptcpdetail->pdata);
|
||||
*datalen=pstream->ptcpdetail->datalen;
|
||||
}
|
||||
else if(pstream->type==STREAM_TYPE_UDP)
|
||||
{
|
||||
data=(char*)(pstream->pudpdetail->pdata);
|
||||
*datalen=pstream->pudpdetail->datalen;
|
||||
}
|
||||
else
|
||||
{
|
||||
data=NULL;
|
||||
*datalen=0;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int kni_filestate2_set(int thread_seq,int colum_index,int bytes,int pktnum)
|
||||
{
|
||||
g_kni_fs2_info.column_value_pkt[thread_seq][colum_index]+=pktnum;
|
||||
g_kni_fs2_info.column_value_bytes[thread_seq][colum_index]+=bytes;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int kni_filestate2_init()
|
||||
{
|
||||
int i=0;
|
||||
// int j=0;
|
||||
int value=1;
|
||||
unsigned int fs2_sport=0;
|
||||
char fs2_filename[KNI_MAX_BUFLEN]={0};
|
||||
char fs2_sip[KNI_MAX_BUFLEN]={0};
|
||||
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"filestat2_filename",fs2_filename,KNI_MAX_BUFLEN,(char*)"./log/kni_fs2.log");
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"filestat2_sip",fs2_sip,KNI_MAX_BUFLEN,(char*)"0.0.0.0");
|
||||
MESA_load_profile_uint_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"filestat2_sport",(unsigned int*)&fs2_sport,0);
|
||||
|
||||
g_kni_fs2_info.handler=FS_create_handle();
|
||||
|
||||
FS_set_para(g_kni_fs2_info.handler, OUTPUT_DEVICE,fs2_filename, strlen(fs2_filename)+1);
|
||||
FS_set_para(g_kni_fs2_info.handler, PRINT_MODE, &value, sizeof(value));
|
||||
FS_set_para(g_kni_fs2_info.handler, STAT_CYCLE, &value, sizeof(value));
|
||||
FS_set_para(g_kni_fs2_info.handler, CREATE_THREAD, &value, sizeof(value));
|
||||
FS_set_para(g_kni_fs2_info.handler, APP_NAME, FS2_APPNAME, strlen(FS2_APPNAME)+1);
|
||||
|
||||
if(fs2_sport!=0)
|
||||
{
|
||||
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;i<FS2_COLUMN_NUM;i++)
|
||||
{
|
||||
g_kni_fs2_info.column_id[i]=FS_register(g_kni_fs2_info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,g_kni_fs2_name[i]);
|
||||
}
|
||||
|
||||
|
||||
FS_start(g_kni_fs2_info.handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void* kni_filestat2(void* arg)
|
||||
{
|
||||
int i=0;
|
||||
int j=0;
|
||||
|
||||
unsigned long long column_value[FS2_COLUMN_NUM];
|
||||
|
||||
kni_filestate2_init();
|
||||
|
||||
while(1)
|
||||
{
|
||||
for(i=0;i<FS2_COLUMN_NUM;i++)
|
||||
{
|
||||
column_value[i]=0;
|
||||
|
||||
for(j=0;j<g_iThreadNum;j++)
|
||||
{
|
||||
column_value[i]+=g_kni_fs2_info.column_value_pkt[j][i];
|
||||
}
|
||||
|
||||
FS_operate(g_kni_fs2_info.handler,g_kni_fs2_info.column_id[i], 0,FS_OP_SET,column_value[i]);
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
53
kni_comm.h
Normal file
53
kni_comm.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef KNI_COMMON_H
|
||||
#define KNI_COMMON_H
|
||||
|
||||
|
||||
#ifndef KNI_MAX_THREADNUM
|
||||
#define KNI_MAX_THREADNUM 64
|
||||
#endif
|
||||
|
||||
|
||||
#define FS2_COLUMN_NUM 9
|
||||
#define FS2_APPNAME "KNI"
|
||||
|
||||
|
||||
enum kni_FS_COLUME
|
||||
{
|
||||
FS2_COLUME_RECV=0,
|
||||
FS2_COLUME_WRITE,
|
||||
FS2_COLUME_READ,
|
||||
FS2_COLUME_SEND,
|
||||
FS2_COLUME_WITELIST_IP,
|
||||
FS2_COLUME_WITELIST_DOMAIN,
|
||||
FS2_COLUME_HTTP,
|
||||
FS2_COLUME_SSL,
|
||||
FS2_COLUME_DROPPKT,
|
||||
};
|
||||
|
||||
|
||||
//field stat2
|
||||
struct kni_fs2_info
|
||||
{
|
||||
screen_stat_handle_t handler;
|
||||
int column_id[FS2_COLUMN_NUM];
|
||||
unsigned long long column_value_pkt[KNI_MAX_THREADNUM][FS2_COLUMN_NUM];
|
||||
unsigned long long column_value_bytes[KNI_MAX_THREADNUM][FS2_COLUMN_NUM];
|
||||
};
|
||||
|
||||
|
||||
|
||||
int kni_log_info_v4(char* module,struct stream_tuple4_v4* addr,unsigned short protocol,char* domain,char* scan_result,char* action);
|
||||
int kni_log_debug_v4(int level,char* module,struct ip* a_packet,char* content);
|
||||
|
||||
int kni_get_ipaddr_v4(void* a_packet,struct stream_tuple4_v4* ipaddr);
|
||||
int kni_get_ipaddr_v6(void* a_packet,struct stream_tuple4_v6* ipaddr);
|
||||
|
||||
int kni_get_tcpinfo(struct kni_wndpro_reply_info* lastpkt_info,struct kni_tcp_hdr* tcphdr,int tcplen,struct ip* ip_hdr);
|
||||
int kni_get_tcpopt(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,unsigned short* mss,unsigned char* winscale,unsigned char* scak,unsigned char* timestamps);
|
||||
char* kni_get_data(const struct streaminfo* pstream,int* datalen);
|
||||
|
||||
int kni_filestate2_set(int thread_seq,int colum_index,int bytes,int pktnum);
|
||||
void* kni_filestat2(void* arg);
|
||||
|
||||
#endif
|
||||
|
||||
702
kni_connect.c
Normal file
702
kni_connect.c
Normal file
@@ -0,0 +1,702 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include "kni_connect.h"
|
||||
#include "kni_entry.h"
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" int sendpacket_do_checksum(unsigned char* buf,int protocol,int len);
|
||||
extern "C" int sendpacket_build_ethernet(unsigned char* dst,unsigned char* src,unsigned short type,const unsigned char* payload,int payload_s,unsigned char* buf);
|
||||
extern "C" unsigned char MESA_dir_reverse(unsigned char route_dir);
|
||||
|
||||
|
||||
|
||||
|
||||
int kni_send_fds(int socket, int *fds, int n,int protocol)
|
||||
{
|
||||
int flags=MSG_NOSIGNAL;
|
||||
struct msghdr msg = {0};
|
||||
struct cmsghdr *cmsg;
|
||||
char buf[CMSG_SPACE(n * sizeof(int))], dup[256]={0};
|
||||
memset(buf, 0, sizeof(buf));
|
||||
// struct iovec io = { .iov_base = &dup, .iov_len = sizeof(struct kni_tlv_info) };
|
||||
struct iovec io = { .iov_base = &dup, .iov_len = sizeof(dup) };
|
||||
|
||||
|
||||
//tlv info
|
||||
struct kni_tlv_info tlv_info;
|
||||
tlv_info.type=KNI_TLV_TYPE_PRO;
|
||||
tlv_info.len=0x0001;
|
||||
tlv_info.value=protocol;
|
||||
memcpy(dup,&tlv_info,sizeof(struct kni_tlv_info));
|
||||
//end
|
||||
|
||||
msg.msg_iov = &io;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = buf;
|
||||
msg.msg_controllen = sizeof(buf);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(n * sizeof(int));
|
||||
|
||||
memcpy ((int *) CMSG_DATA(cmsg), fds, n * sizeof (int));
|
||||
|
||||
// if (sendmsg (socket, &msg, 0) < 0)
|
||||
if (sendmsg (socket, &msg, flags) < 0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"kni_send_fds","sendmsg()error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kni_sendfds_domain()
|
||||
{
|
||||
int ret=0;
|
||||
long fds_len=KNI_FDS_NUM*sizeof(int);
|
||||
int fds[KNI_FDS_NUM]={0};
|
||||
|
||||
while(1)
|
||||
{
|
||||
memset(fds,0,KNI_FDS_NUM*sizeof(int));
|
||||
fds_len=KNI_FDS_NUM*sizeof(int);
|
||||
|
||||
ret=MESA_lqueue_get_tail(g_kni_structinfo.lqueue_for_domain,fds,&fds_len);
|
||||
if(ret==MESA_QUEUE_RET_QEMPTY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_READTUN,"MESA_lqueue_try_get_tail() error!ret:%d\n",ret);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
ret=kni_send_fds(g_kni_comminfo.fd_domain,fds,2,fds[KNI_FDS_INDEX_PROTOCOL]);
|
||||
if(ret<0) //check errno
|
||||
{
|
||||
g_kni_comminfo.kni_mode_cur=KNI_MODE_BYPASS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fds[KNI_FDS_INDEX_CLIENT]);
|
||||
close(fds[KNI_FDS_INDEX_SERVER]);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kni_connect_domain()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
g_kni_comminfo.fd_domain=init_domain_fd();
|
||||
if(g_kni_comminfo.fd_domain<0)
|
||||
{
|
||||
sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_kni_comminfo.kni_mode_cur=KNI_MODE_WORK;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************************************************************
|
||||
name:
|
||||
function:
|
||||
return:
|
||||
*********************************************************************************************************************/
|
||||
void* kni_process_domain(void* arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if(g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS)
|
||||
{
|
||||
kni_connect_domain();
|
||||
}
|
||||
else
|
||||
{
|
||||
kni_sendfds_domain();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int init_domain_fd()
|
||||
{
|
||||
|
||||
int i_fd = 0;
|
||||
struct sockaddr_un addr;
|
||||
int i_addr_len = sizeof( struct sockaddr_un );
|
||||
|
||||
if ( ( i_fd = socket( AF_UNIX, SOCK_STREAM, 0 ) ) < 0 )
|
||||
// if ( ( i_fd = socket( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 )
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"init_domain_fd():socket error,errno is %d,%s,,action:%s",errno,strerror(errno),KNI_ACTION_EXIT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//fill socket adress structure with server's address
|
||||
memset( &addr, 0, sizeof( addr ) );
|
||||
addr.sun_family = AF_UNIX;
|
||||
// strncpy( addr.sun_path, serverpath, sizeof( addr.sun_path ) - 1 );
|
||||
strncpy( addr.sun_path, g_kni_comminfo.domain_path, sizeof( addr.sun_path ) - 1 );
|
||||
|
||||
|
||||
if ( connect( i_fd, ( struct sockaddr * )&addr, i_addr_len ) < 0 )
|
||||
{
|
||||
close(i_fd);
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"init_domain_fd():connect error,errno is %d,%s,action:%s",errno,strerror(errno),KNI_ACTION_EXIT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"init_domain_fd","domain socket connect succ! ");
|
||||
return i_fd;
|
||||
}
|
||||
|
||||
int init_kni_domain()
|
||||
{
|
||||
#ifndef KNI_DEBUG_TCPREPAIR
|
||||
|
||||
pthread_t pid_pro_domain;
|
||||
|
||||
g_kni_comminfo.fd_domain=init_domain_fd();
|
||||
if(g_kni_comminfo.fd_domain<0)
|
||||
{
|
||||
g_kni_comminfo.kni_mode_cur=KNI_MODE_BYPASS;
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"init_domain_fd()error");
|
||||
}
|
||||
|
||||
pthread_create(&pid_pro_domain,NULL,kni_process_domain,NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
int tun_set_queue(int fd, int enable)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
|
||||
if (enable)
|
||||
ifr.ifr_flags = IFF_ATTACH_QUEUE;
|
||||
else
|
||||
ifr.ifr_flags = IFF_DETACH_QUEUE;
|
||||
|
||||
return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
|
||||
}
|
||||
|
||||
int tun_error(int i,int* fds)
|
||||
{
|
||||
|
||||
for (--i; i >= 0; i--)
|
||||
{
|
||||
close(fds[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
|
||||
* IFF_TAP - TAP device
|
||||
*
|
||||
* IFF_NO_PI - Do not provide packet information
|
||||
* IFF_MULTI_QUEUE - Create a queue of multiqueue device
|
||||
*/
|
||||
int tun_alloc_mq(char *dev, int queues, int *fds)
|
||||
{
|
||||
int i=0;
|
||||
int err=0;
|
||||
int fd;
|
||||
int flag=0;
|
||||
struct ifreq ifr;
|
||||
|
||||
|
||||
char *clonedev = (char*)"/dev/net/tun";
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE;
|
||||
if (*dev)
|
||||
{
|
||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||
}
|
||||
|
||||
for (i = 0; i < queues; i++)
|
||||
{
|
||||
if ((fd = open(clonedev, O_RDWR)) < 0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"tun_alloc_mq():open error,errno is:%d,%s,action:%s",errno,strerror(errno),KNI_ACTION_EXIT);
|
||||
tun_error(i,fds);
|
||||
return -1;
|
||||
}
|
||||
err = ioctl(fd, TUNSETIFF, (void *)&ifr);
|
||||
if (err)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"tun_alloc_mq():ioctl error,errno is:%d,%s,action:%s",errno,strerror(errno),KNI_ACTION_EXIT);
|
||||
close(fd);
|
||||
tun_error(i,fds);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//20180618 add set noblock
|
||||
flag= fcntl(fd, F_GETFL, 0);
|
||||
if(flag<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"fcntl():getfl error,errno is:%d,%s",errno,strerror(errno));
|
||||
}
|
||||
|
||||
if( fcntl( fd, F_SETFL, flag|O_NONBLOCK ) < 0 )
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"fcntl():setfl error,errno is:%d,%s",errno,strerror(errno));
|
||||
}
|
||||
|
||||
//end
|
||||
|
||||
fds[i] = fd;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int tun_read_data(int fd,char* recv_buf,int max_buflen)
|
||||
{
|
||||
int recv_len=0;
|
||||
|
||||
int ret=0;
|
||||
int max_fd = 0;
|
||||
fd_set alive_readfd;
|
||||
|
||||
FD_ZERO(&alive_readfd);
|
||||
FD_SET(fd, &alive_readfd);
|
||||
max_fd = fd;
|
||||
|
||||
ret = select(max_fd + 1, &alive_readfd, NULL, NULL, NULL);
|
||||
if (ret <= 0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL, "keep_alive_action function", "select function errno %d is %s!", errno, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
recv_len = read(fd, recv_buf, KNI_MAX_BUFLEN);
|
||||
if(recv_len <0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"tun_read_data error %d, %s\n",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return recv_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char tun_write_data(int fd,char* send_buf,int send_buflen,struct streaminfo* pstream,int thread_seq)
|
||||
{
|
||||
char ret=APP_STATE_DROPPKT|APP_STATE_GIVEME;
|
||||
int succ_sendlen=0;
|
||||
|
||||
succ_sendlen = write(fd, send_buf,send_buflen);
|
||||
if((succ_sendlen<0)&&(pstream!=NULL))
|
||||
{
|
||||
kni_filestate2_set(thread_seq,FS2_COLUME_DROPPKT,0,1);
|
||||
MESA_kill_tcp(pstream,(const void*)send_buf);
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"write() error %d, %s",errno,strerror(errno));
|
||||
ret=APP_STATE_DROPPKT|APP_STATE_DROPME;
|
||||
}
|
||||
else if(succ_sendlen<send_buflen)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"succ_sendlen is %d,send_buflen is %d",succ_sendlen,send_buflen);
|
||||
}
|
||||
|
||||
kni_filestate2_set(thread_seq,FS2_COLUME_WRITE,0,1);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tun_write_data_v6(int fd,char* send_buf,int send_buflen)
|
||||
{
|
||||
int succ_sendlen=0;
|
||||
|
||||
succ_sendlen = write(fd, send_buf,send_buflen);
|
||||
if(succ_sendlen<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"write() error!msg is %s",strerror(errno));
|
||||
}
|
||||
else if(succ_sendlen<send_buflen)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_WRITETUN,"succ_sendlen is %d,send_buflen is %d",succ_sendlen,send_buflen);
|
||||
}
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_DEBUG,KNI_MODULE_WRITETUN,"write to tun completed,,send_buflen is %d",succ_sendlen);
|
||||
|
||||
return succ_sendlen;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int init_kni_tun()
|
||||
{
|
||||
int ret;
|
||||
|
||||
g_kni_comminfo.thread_num=g_iThreadNum;
|
||||
if(g_kni_comminfo.thread_num<=0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"thread_num:%d,action:%s",g_kni_comminfo.thread_num,KNI_ACTION_EXIT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_kni_comminfo.fd_tun=(int*)malloc(g_kni_comminfo.thread_num*sizeof(int));
|
||||
memset(g_kni_comminfo.fd_tun,0,g_kni_comminfo.thread_num*sizeof(int));
|
||||
|
||||
ret=tun_alloc_mq(g_kni_comminfo.tun_name,g_kni_comminfo.thread_num,g_kni_comminfo.fd_tun);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int kni_sendpkt_routdir(int thread_seq,int iplen,char* ip,struct stream_tuple4_v4* ipv4_addr,int iprever_flag,int routdir,uchar* smac,uchar* dmac)
|
||||
{
|
||||
if((routdir!=0)&&(routdir!=1))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_DEBUG,"kni_sendpkt_routdir","routdir:%d",routdir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret=0;
|
||||
int buflen=iplen+KNI_ETHER_LEN;
|
||||
|
||||
unsigned char buf[2000]={0};
|
||||
unsigned short eth_type=0x0800;
|
||||
|
||||
uchar* tmp_smac;
|
||||
uchar* tmp_dmac;
|
||||
|
||||
char* if_name=NULL;
|
||||
if(iprever_flag==0)
|
||||
{
|
||||
tmp_smac=smac;
|
||||
tmp_dmac=dmac;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_smac=dmac;
|
||||
tmp_dmac=smac;
|
||||
}
|
||||
|
||||
if_name=g_kni_cardname[1-routdir];
|
||||
|
||||
struct ifreq ifr;
|
||||
size_t ifname_len=strlen(if_name);
|
||||
if(ifname_len<sizeof(ifr.ifr_name))
|
||||
{
|
||||
memset(ifr.ifr_name,0,IFNAMSIZ);
|
||||
memcpy(ifr.ifr_name,if_name,ifname_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"interface name :%s is too long\n",if_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(-1==ioctl(g_kni_comminfo.ipv4_fd[thread_seq],SIOCGIFINDEX,&ifr))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"get if index error:%d,%s,name:%d",errno,strerror(errno),if_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_ll addr={0};
|
||||
addr.sll_family=AF_PACKET;
|
||||
addr.sll_halen=ETHER_ADDR_LEN;
|
||||
addr.sll_ifindex=ifr.ifr_ifindex;
|
||||
addr.sll_protocol=htons(ETH_P_IP);
|
||||
memcpy(addr.sll_addr,tmp_dmac,ETHER_ADDR_LEN);
|
||||
|
||||
|
||||
if(ioctl(g_kni_comminfo.ipv4_fd[thread_seq],SIOCGIFHWADDR,&ifr)==-1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
sendpacket_build_ethernet((unsigned char*)tmp_dmac,(unsigned char*)tmp_smac,eth_type,(const unsigned char*)ip,iplen,(unsigned char*)buf);
|
||||
|
||||
ret=sendto(g_kni_comminfo.ipv4_fd[thread_seq],buf,buflen,0,(struct sockaddr*)&addr,sizeof(addr));
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_FATAL,KNI_MODULE_SENDPKT,"sendto() error,errno:%d,msg:%s!",errno,strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
kni_filestate2_set(thread_seq,FS2_COLUME_SEND,0,1);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int kni_keepalive_replay(struct stream_tuple4_v4* ipv4_addr,int iprever_flag,struct kni_htable_datainfo* datainfo,void* a_packet,int iplen,int thread_seq)
|
||||
{
|
||||
#ifdef KNI_DEBUG_TCPREPAIR
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if(!g_kni_switch_info.replay_win_update)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int index=1-iprever_flag;
|
||||
// unsigned short ipid=random()%65535;
|
||||
|
||||
struct ip* iphdr=(struct ip*)a_packet;
|
||||
struct tcphdr* tcphdr=(struct tcphdr*)((char*)iphdr+4*(iphdr->ip_hl));
|
||||
struct kni_wndpro_reply_info* tcpinfo=&(datainfo->lastpkt_info[index]);
|
||||
|
||||
struct ip* snd_iphdr=NULL;
|
||||
struct tcphdr* snd_tcphdr=NULL;
|
||||
char* sendbuf=(char*)malloc(iplen);
|
||||
memcpy(sendbuf,a_packet,iplen);
|
||||
|
||||
snd_iphdr=(struct ip*)sendbuf;
|
||||
snd_tcphdr=(struct tcphdr*)((char*)snd_iphdr+4*(snd_iphdr->ip_hl));
|
||||
|
||||
(snd_iphdr->ip_src).s_addr=(iphdr->ip_dst).s_addr;
|
||||
(snd_iphdr->ip_dst).s_addr=(iphdr->ip_src).s_addr;
|
||||
// snd_iphdr->ip_id=ipid;
|
||||
// snd_iphdr->ip_id=htons(datainfo->lastpkt_info[index].ipid+1);
|
||||
// snd_iphdr->ip_ttl=datainfo->lastpkt_info[index].ttl;
|
||||
|
||||
snd_tcphdr->source=tcphdr->dest;
|
||||
snd_tcphdr->dest=tcphdr->source;
|
||||
snd_tcphdr->seq=htonl(tcpinfo->seq+tcpinfo->len);
|
||||
snd_tcphdr->ack_seq=htonl(tcpinfo->ack);
|
||||
|
||||
|
||||
if(tcpinfo->syn_flag==1)
|
||||
{
|
||||
snd_tcphdr->seq=htonl(ntohl(snd_tcphdr->seq)+1);
|
||||
}
|
||||
/*
|
||||
if(iprever_flag==0)
|
||||
{
|
||||
snd_iphdr->ip_id=ipid;
|
||||
snd_tcphdr->window=htons((win>>win_scale)+1);
|
||||
}
|
||||
*/
|
||||
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_TCP,(iplen-4*(iphdr->ip_hl)));
|
||||
sendpacket_do_checksum((unsigned char*)sendbuf,IPPROTO_IP,sizeof(struct ip));
|
||||
|
||||
tun_write_data(g_kni_comminfo.fd_tun[thread_seq],sendbuf,iplen,NULL,thread_seq);
|
||||
|
||||
kni_log_debug_v4(RLOG_LV_DEBUG,(char*)"win_update",(struct ip*)a_packet,(char*)"recv tcp_repair windows update,and replay");
|
||||
|
||||
free(sendbuf);
|
||||
sendbuf=NULL;
|
||||
|
||||
datainfo->wndpro_flag[index]=1;
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
long kni_readtun_htable_cb_v4(void* data,const unsigned char* key,unsigned int size,void* user_arg)
|
||||
{
|
||||
long result=0;
|
||||
struct stream_tuple4_v4* ipv4_addr=(struct stream_tuple4_v4*)key;
|
||||
struct args_read_tun* args=(struct args_read_tun*)user_arg;
|
||||
struct kni_htable_datainfo* datainfo=(struct kni_htable_datainfo*)data;
|
||||
|
||||
if(datainfo!=NULL)
|
||||
{
|
||||
memcpy(args->smac,datainfo->smac,KNI_MACADDR_LEN);
|
||||
memcpy(args->dmac,datainfo->dmac,KNI_MACADDR_LEN);
|
||||
if(args->iprevers==0)
|
||||
{
|
||||
args->routdir=datainfo->route_dir;
|
||||
}
|
||||
else
|
||||
{
|
||||
// args->routdir=MESA_dir_reverse(datainfo->route_dir);
|
||||
args->routdir=1-datainfo->route_dir;
|
||||
|
||||
}
|
||||
|
||||
if(datainfo->wndpro_flag[1-args->iprevers]>0)
|
||||
{
|
||||
result=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
kni_keepalive_replay(ipv4_addr,args->iprevers,datainfo,args->a_packet,args->iplen,args->thread_seq);
|
||||
result=1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
#ifdef KNI_DEBUG_TCPREPAIR
|
||||
else if(ipv4_addr->saddr==1698867392)
|
||||
{
|
||||
printf("sip is 192.168.66.101\n");
|
||||
args->smac[0]=0x18;
|
||||
args->smac[1]=0x66;
|
||||
args->smac[2]=0xda;
|
||||
args->smac[3]=0xe5;
|
||||
args->smac[4]=0xfa;
|
||||
args->smac[5]=0xa1;
|
||||
|
||||
args->dmac[0]=0xe8;
|
||||
args->dmac[1]=0x61;
|
||||
args->dmac[2]=0x1f;
|
||||
args->dmac[3]=0x13;
|
||||
args->dmac[4]=0x70;
|
||||
args->dmac[5]=0x7a;
|
||||
result=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
kni_log_debug_v4(RLOG_LV_INFO,"htable_cb",(struct ip*)args->a_packet,(char*)"read_tun,data=NULL,sip not 192.168.66.101");
|
||||
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int kni_process_readdata(int thread_seq,int buflen,char* buf)
|
||||
{
|
||||
int iprever_flag=0;
|
||||
long result=0;
|
||||
|
||||
struct ip* iphdr=(struct ip*)buf;
|
||||
struct stream_tuple4_v4 ipv4_addr;
|
||||
|
||||
struct args_read_tun args;
|
||||
|
||||
if(iphdr->ip_v==4)
|
||||
{
|
||||
iprever_flag=kni_get_ipaddr_v4((void*)buf,&ipv4_addr);
|
||||
|
||||
args.a_packet=buf;
|
||||
args.iplen=buflen;
|
||||
args.iprevers=iprever_flag;
|
||||
args.thread_seq=thread_seq;
|
||||
|
||||
MESA_htable_search_cb(g_kni_structinfo.htable_to_tun_v4,(unsigned char*)&ipv4_addr,sizeof(struct stream_tuple4_v4),kni_readtun_htable_cb_v4,(void*)&args,&result);
|
||||
if(result==1)
|
||||
{
|
||||
|
||||
// kni_sendpkt_eth(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac);
|
||||
kni_sendpkt_routdir(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
name:
|
||||
function:
|
||||
return:
|
||||
*********************************************************************************************************************/
|
||||
void* kni_read_tun(void* arg)
|
||||
{
|
||||
int thread_seq=*(int*)arg;
|
||||
|
||||
int recv_len=0;
|
||||
char recv_buf[KNI_MAX_BUFLEN] = {0};
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS)
|
||||
{
|
||||
sleep(KNI_USLEEP_TIME);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
recv_len=0;
|
||||
memset(recv_buf,0,KNI_MAX_BUFLEN);
|
||||
|
||||
recv_len=tun_read_data(g_kni_comminfo.fd_tun[thread_seq],recv_buf, KNI_MAX_BUFLEN);
|
||||
if(recv_len <0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_READTUN,"tun_read_data()error,recv_len:%d",recv_len);
|
||||
}
|
||||
else if(recv_len>0)
|
||||
{
|
||||
kni_filestate2_set(thread_seq,FS2_COLUME_READ,0,1);
|
||||
kni_process_readdata(thread_seq,recv_len,recv_buf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
19
kni_connect.h
Normal file
19
kni_connect.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef KNI_CONNECT_H
|
||||
#define KNI_CONNECT_H
|
||||
|
||||
|
||||
|
||||
|
||||
int kni_send_fds(int socket, int *fds, int n,int protocol);
|
||||
char tun_write_data(int fd,char* send_buf,int send_buflen,struct streaminfo* pstream,int thread_seq);
|
||||
|
||||
|
||||
int init_domain_fd();
|
||||
int init_kni_domain();
|
||||
int init_kni_tun();
|
||||
|
||||
void* kni_read_tun(void* arg);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
916
kni_entry.c
Normal file
916
kni_entry.c
Normal file
@@ -0,0 +1,916 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/ethernet.h>
|
||||
#include "kni_entry.h"
|
||||
|
||||
|
||||
|
||||
int g_kni_version_VERSION_20180822;
|
||||
|
||||
struct kni_var_comm g_kni_comminfo;
|
||||
struct kni_var_struct g_kni_structinfo;
|
||||
struct kni_var_maat g_kni_maatinfo;
|
||||
struct kni_fs2_info g_kni_fs2_info;
|
||||
struct kni_switch_info g_kni_switch_info;
|
||||
|
||||
char g_kni_cardname[KNI_CARD_NUM][KNI_CONF_MAXLEN];
|
||||
int g_kni_threadseq[KNI_MAX_THREADNUM];
|
||||
|
||||
|
||||
|
||||
|
||||
int kni_init_pmeinfo(void** pme)
|
||||
{
|
||||
struct kni_pme_info* pmeinfo=(struct kni_pme_info*)malloc(sizeof(struct kni_pme_info));
|
||||
memset(pmeinfo,0,sizeof(struct kni_pme_info));
|
||||
*pme=pmeinfo;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int kni_free_pmeinfo(void** pme)
|
||||
{
|
||||
struct kni_pme_info* pmeinfo=(struct kni_pme_info*)*pme;
|
||||
|
||||
Maat_clean_status(&(pmeinfo->mid));
|
||||
free(pmeinfo);
|
||||
|
||||
pmeinfo=NULL;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
return :state_flag
|
||||
kni_bmd:STAT_FLAG_SNIBMD
|
||||
not kni_bmd:STAT_FLAG_SSL_NOBMD
|
||||
***************************************************************************************/
|
||||
int kni_scan_domain(char* domain,int domain_len,int thread_seq,scan_status_t mid)
|
||||
{
|
||||
int i=0;
|
||||
int action=KNI_ACTION_NONE;
|
||||
|
||||
int string_scan_num=0;
|
||||
int found_pos;
|
||||
struct Maat_rule_t maat_result[KNI_MAX_SAMENUM];
|
||||
|
||||
string_scan_num=Maat_full_scan_string(g_kni_maatinfo.maat_feather,g_kni_maatinfo.tableid_domain,CHARSET_GBK,domain,domain_len,maat_result,&found_pos,KNI_MAX_SAMENUM,&mid,thread_seq);
|
||||
|
||||
|
||||
for(i=0;i<string_scan_num;i++)
|
||||
{
|
||||
action=abs(maat_result[i].action);
|
||||
if(action==KNI_ACTION_WHITELIST)
|
||||
{
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
return :action
|
||||
default:ipscan_num =0 or =1,not >1
|
||||
***************************************************************************************/
|
||||
int kni_scan_ip(struct ipaddr* addr,int thread_seq,int protocol,scan_status_t mid)
|
||||
{
|
||||
int i=0;
|
||||
int action=KNI_ACTION_NONE;
|
||||
|
||||
int ipscan_num=0;
|
||||
struct Maat_rule_t maat_result[KNI_MAX_SAMENUM];
|
||||
|
||||
ipscan_num=Maat_scan_proto_addr(g_kni_maatinfo.maat_feather,g_kni_maatinfo.tableid_ip,addr,protocol,maat_result,KNI_MAX_SAMENUM,&mid,thread_seq);
|
||||
|
||||
for(i=0;i<ipscan_num;i++)
|
||||
{
|
||||
action=abs(maat_result[i].action);
|
||||
if(action==KNI_ACTION_WHITELIST)
|
||||
{
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int kni_htable_add(const struct streaminfo* pstream,const struct ip* ip_hdr,struct kni_pme_info* pmeinfo)
|
||||
{
|
||||
int iprevers=0;
|
||||
struct stream_tuple4_v4 ipv4_addr;
|
||||
struct layer_addr_mac* mac_addr=(struct layer_addr_mac*)((char*)ip_hdr-KNI_ETHER_LEN);
|
||||
struct kni_htable_datainfo* datainfo=(struct kni_htable_datainfo*)malloc(sizeof(struct kni_htable_datainfo));
|
||||
memset(datainfo,0,sizeof(struct kni_htable_datainfo));
|
||||
|
||||
iprevers=kni_get_ipaddr_v4((void*)ip_hdr,&ipv4_addr);
|
||||
|
||||
//send pkt info
|
||||
if(iprevers==0)
|
||||
{
|
||||
datainfo->route_dir=pstream->routedir;
|
||||
memcpy(datainfo->smac,mac_addr->src_mac,MAC_ADDR_LEN);
|
||||
memcpy(datainfo->dmac,mac_addr->dst_mac,MAC_ADDR_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
// datainfo->route_dir=MESA_dir_reverse(pstream->routedir);
|
||||
datainfo->route_dir=1-pstream->routedir;
|
||||
memcpy(datainfo->smac,mac_addr->dst_mac,MAC_ADDR_LEN);
|
||||
memcpy(datainfo->dmac,mac_addr->src_mac,MAC_ADDR_LEN);
|
||||
}
|
||||
|
||||
//send wnd_pro_reply info
|
||||
memcpy(datainfo->wnscal,pmeinfo->wnscal,KNI_DIR_DOUBLE*sizeof(unsigned char));
|
||||
memcpy(datainfo->mss,pmeinfo->mss,KNI_DIR_DOUBLE*sizeof(unsigned short));
|
||||
memcpy(&(datainfo->lastpkt_info),&(pmeinfo->lastpkt_info),KNI_DIR_DOUBLE*sizeof(struct kni_wndpro_reply_info));
|
||||
|
||||
MESA_htable_add(g_kni_structinfo.htable_to_tun_v4,(unsigned char*)&ipv4_addr,sizeof(struct stream_tuple4_v4),(void*)datainfo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
return :state_flag
|
||||
ssl:STAT_FLAG_SSL_NOBMD
|
||||
not ssl:STAT_FLAG_NOTSSL
|
||||
***************************************************************************************/
|
||||
int kni_judge_ssl(char* tcp_data,int tcp_datalen,char* sni,int* sni_len)
|
||||
{
|
||||
int ssl_header_len=0;
|
||||
char* ssl_header=NULL;
|
||||
unsigned char content_type=0;
|
||||
unsigned short version_in_header=0;
|
||||
unsigned short len_in_header=0;
|
||||
|
||||
|
||||
int ssl_body_len=0;
|
||||
char* ssl_body=NULL;
|
||||
unsigned char handshark_type=0;
|
||||
unsigned int len_in_body=0;
|
||||
unsigned short version_in_body=0;
|
||||
unsigned char session_id_len=0;
|
||||
unsigned short ciphersuite_len=0;
|
||||
unsigned char compression_method_len=0;
|
||||
|
||||
|
||||
int ssl_extention_len=0;
|
||||
char* ssl_extention=NULL;
|
||||
unsigned short extension_len_less=0;
|
||||
unsigned short type_in_extension=0;
|
||||
unsigned short len_in_extension=0;
|
||||
|
||||
//ssl header
|
||||
ssl_header=tcp_data;
|
||||
|
||||
content_type=*(unsigned char*)&ssl_header[ssl_header_len];
|
||||
if(content_type!=SSL_CONTENTTYPE_HANDSHAKE)
|
||||
{
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
ssl_header_len+=1;
|
||||
|
||||
version_in_header=ntohs(*(unsigned short*)&(ssl_header[ssl_header_len]));
|
||||
if((version_in_header!=SSL_VERSION_TLS1_0)&&(version_in_header!=SSL_VERSION_TLS1_1)&&(version_in_header!=SSL_VERSION_TLS1_2))
|
||||
{
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
ssl_header_len+=2;
|
||||
|
||||
len_in_header=ntohs(*(unsigned short*)&(ssl_header[ssl_header_len]));
|
||||
if(len_in_header!=tcp_datalen-SSL_HEADER_LEN)
|
||||
{
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
ssl_header_len+=2;
|
||||
|
||||
//ssl body
|
||||
ssl_body=ssl_header+ssl_header_len;
|
||||
|
||||
handshark_type=*(unsigned char*)&(ssl_body[ssl_body_len]);
|
||||
if(handshark_type!=SSL_HANDSHAR_TYPE_CLIENTHELLO)
|
||||
{
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
ssl_body_len+=1;
|
||||
|
||||
// memcpy(&len_in_body,&ssl_body[ssl_body_len],3);
|
||||
len_in_body=*(unsigned char*)&ssl_body[ssl_body_len+2]+256*(*(unsigned char*)&ssl_body[ssl_body_len+1])+65536*(*(unsigned char*)&ssl_body[ssl_body_len]);
|
||||
if(len_in_body!=(len_in_header-SSL_BODY_LEN))
|
||||
{
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
|
||||
ssl_body_len+=3;
|
||||
|
||||
version_in_body=ntohs(*(unsigned short*)&(ssl_body[ssl_body_len]));
|
||||
if((version_in_body!=SSL_VERSION_TLS1_0)&&(version_in_body!=SSL_VERSION_TLS1_1)&&(version_in_body!=SSL_VERSION_TLS1_2))
|
||||
{
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
ssl_body_len+=2;
|
||||
|
||||
ssl_body_len+=32; //4byte time,28bytes random
|
||||
|
||||
session_id_len=*(unsigned char*)&(ssl_body[ssl_body_len]);
|
||||
ssl_body_len+=1;
|
||||
ssl_body_len+=session_id_len;
|
||||
|
||||
ciphersuite_len=ntohs(*(unsigned short*)&(ssl_body[ssl_body_len]));
|
||||
ssl_body_len+=2;
|
||||
ssl_body_len+=ciphersuite_len;
|
||||
|
||||
compression_method_len=*(unsigned char*)&(ssl_body[ssl_body_len]);
|
||||
ssl_body_len+=1;
|
||||
ssl_body_len+=compression_method_len;
|
||||
|
||||
//ssl extention
|
||||
ssl_extention=ssl_body+ssl_body_len;
|
||||
|
||||
extension_len_less=ntohs(*(unsigned short*)&ssl_extention[ssl_extention_len]);
|
||||
if(extension_len_less!=len_in_body-2-32-1-session_id_len-2-ciphersuite_len-1-compression_method_len-2)
|
||||
{
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
ssl_extention_len+=2;
|
||||
|
||||
while(ssl_extention_len<extension_len_less)
|
||||
{
|
||||
type_in_extension=ntohs(*(unsigned short*)&ssl_extention[ssl_extention_len]);
|
||||
ssl_extention_len+=2;
|
||||
|
||||
len_in_extension=ntohs(*(unsigned short*)&ssl_extention[ssl_extention_len]);
|
||||
ssl_extention_len+=2;
|
||||
|
||||
if(type_in_extension==SSL_EXTENSION_TYPE_SNI)
|
||||
{
|
||||
if(len_in_extension>KNI_SNI_MAXLEN)
|
||||
{
|
||||
//error
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
|
||||
if(len_in_extension>KNI_DEFAULT_MTU)
|
||||
{
|
||||
len_in_extension=KNI_DEFAULT_MTU;
|
||||
}
|
||||
memcpy(sni,&ssl_extention[ssl_extention_len],len_in_extension);
|
||||
*sni_len=len_in_extension;
|
||||
|
||||
return KNI_FLAG_SSL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ssl_extention_len+=len_in_extension;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return KNI_FLAG_UNKNOW;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int kni_judge_http(const struct streaminfo *stream,char* domain,int* domain_len)
|
||||
{
|
||||
int val=1;
|
||||
struct kni_http_project* host=(struct kni_http_project*)project_req_get_struct(stream,g_kni_comminfo.project_id);
|
||||
if(host==NULL)
|
||||
{
|
||||
*domain_len=0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*domain_len=host->host_len>KNI_DEFAULT_MTU?KNI_DEFAULT_MTU:host->host_len;
|
||||
memcpy(domain,host->host,*domain_len);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int kni_protocol_identify(const struct streaminfo* pstream,char* tcp_data,int tcp_datalen,char* domain,int* domain_len)
|
||||
{
|
||||
if(kni_judge_http(pstream,domain,domain_len)==1)
|
||||
{
|
||||
kni_filestate2_set(pstream->threadnum,FS2_COLUME_HTTP,0,1);
|
||||
return KNI_FLAG_HTTP;
|
||||
}
|
||||
else if(kni_judge_ssl(tcp_data,tcp_datalen,domain,domain_len)==KNI_FLAG_SSL)
|
||||
{
|
||||
kni_filestate2_set(pstream->threadnum,FS2_COLUME_SSL,0,1);
|
||||
return KNI_FLAG_SSL;
|
||||
}
|
||||
|
||||
return KNI_FLAG_NOTPROC;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char kni_first_tcpdata(const struct streaminfo* pstream,const struct ip* ip_hdr,struct kni_pme_info* pmeinfo,char* data,int datalen)
|
||||
{
|
||||
char ret=APP_STATE_FAWPKT|APP_STATE_DROPME;
|
||||
|
||||
int domain_len=0;
|
||||
char domain[KNI_DEFAULT_MTU]={0};
|
||||
|
||||
int action=KNI_ACTION_NONE;
|
||||
|
||||
pmeinfo->status_flag=kni_protocol_identify(pstream,data,datalen,domain,&domain_len);
|
||||
|
||||
if((pmeinfo->status_flag==KNI_FLAG_HTTP) ||(pmeinfo->status_flag==KNI_FLAG_SSL))
|
||||
{
|
||||
action=kni_scan_domain(domain,domain_len,pstream->threadnum,pmeinfo->mid);
|
||||
if(action==KNI_ACTION_WHITELIST)
|
||||
{
|
||||
kni_filestate2_set(pstream->threadnum,FS2_COLUME_WITELIST_DOMAIN,0,1);
|
||||
kni_log_info_v4((char*)KNI_MODULE_INFO,pstream->addr.tuple4_v4,pmeinfo->status_flag,domain,(char*)"WHITE_LIST_DOMAIN",(char*)"BYPASS");
|
||||
|
||||
pmeinfo->status_flag=KNI_FLAG_NOTPROC;
|
||||
return ret;
|
||||
}
|
||||
//20180803 add
|
||||
else if((g_kni_switch_info.maat_default_mode==KNI_DEFAULT_MODE_BYPASS)&&(action==KNI_ACTION_NONE)&&(pmeinfo->ip_not_hit))
|
||||
{
|
||||
kni_log_info_v4((char*)KNI_MODULE_INFO,pstream->addr.tuple4_v4,pmeinfo->status_flag,domain,(char*)"NOT_HIT",(char*)"BYPASS");
|
||||
|
||||
pmeinfo->status_flag=KNI_FLAG_NOTPROC;
|
||||
return ret;
|
||||
}
|
||||
//end
|
||||
|
||||
if(tcp_repair_process(pstream,ip_hdr,pmeinfo,pmeinfo->status_flag)<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_INFO,"tcp_repair_process","tcp_repair_process() error!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
kni_htable_add(pstream,ip_hdr,pmeinfo);
|
||||
kni_log_info_v4((char*)KNI_MODULE_INFO,pstream->addr.tuple4_v4,pmeinfo->status_flag,domain,(char*)"INTERCEPT",(char*)"INTERCEPT");
|
||||
|
||||
ret=APP_STATE_DROPPKT|APP_STATE_GIVEME;
|
||||
}
|
||||
else
|
||||
{
|
||||
kni_log_info_v4((char*)KNI_MODULE_INFO,pstream->addr.tuple4_v4,pmeinfo->status_flag,NULL,(char*)"NOT_HTTP_SSL",(char*)"BYPASS");
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char kni_pending_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const struct ip* ip_hdr,int protocol)
|
||||
{
|
||||
char ret=APP_STATE_FAWPKT|APP_STATE_DROPME;
|
||||
|
||||
char* data=NULL;
|
||||
int datalen=0;
|
||||
|
||||
int ipscan_action=0;
|
||||
int iplen=ntohs(ip_hdr->ip_len);
|
||||
struct kni_tcp_hdr* tcphdr=(struct kni_tcp_hdr*)((char*)ip_hdr+4*(ip_hdr->ip_hl));
|
||||
|
||||
|
||||
ipscan_action=kni_scan_ip((struct ipaddr*)&(pstream->addr),thread_seq,protocol,pmeinfo->mid);
|
||||
if(ipscan_action==KNI_ACTION_WHITELIST)
|
||||
{
|
||||
kni_log_info_v4((char*)KNI_MODULE_INFO,pstream->addr.tuple4_v4,0,NULL,(char*)"WHITE_LIST_IP",(char*)"BYPASS");
|
||||
kni_filestate2_set(thread_seq,FS2_COLUME_WITELIST_IP,0,1);
|
||||
return ret;
|
||||
}
|
||||
else if((g_kni_switch_info.maat_default_mode==KNI_DEFAULT_MODE_BYPASS)&&(ipscan_action==KNI_ACTION_NONE))
|
||||
{
|
||||
pmeinfo->ip_not_hit=1;
|
||||
}
|
||||
|
||||
pmeinfo->status_flag=KNI_FLAG_UNKNOW;
|
||||
|
||||
data=kni_get_data(pstream,&datalen);
|
||||
kni_get_tcpopt(tcphdr,iplen-4*(ip_hdr->ip_hl)-datalen,&(pmeinfo->mss[pstream->curdir-1]),&(pmeinfo->wnscal[pstream->curdir-1]),&(pmeinfo->sack[pstream->curdir-1]),&(pmeinfo->timestamps[pstream->curdir-1]));
|
||||
|
||||
kni_get_tcpinfo(&(pmeinfo->lastpkt_info[pstream->curdir-1]),tcphdr,ntohs(ip_hdr->ip_len)-4*ip_hdr->ip_hl-4*tcphdr->th_off,(struct ip*)ip_hdr);
|
||||
|
||||
#ifndef KNI_DEBUG_TCPREPAIR
|
||||
if(datalen>0)
|
||||
#endif
|
||||
{
|
||||
ret=kni_first_tcpdata(pstream,ip_hdr,pmeinfo,data,datalen);
|
||||
if((pmeinfo->status_flag==KNI_FLAG_HTTP) ||(pmeinfo->status_flag==KNI_FLAG_SSL))
|
||||
{
|
||||
ret=tun_write_data(g_kni_comminfo.fd_tun[thread_seq],(char*)ip_hdr,iplen,(struct streaminfo*)pstream,thread_seq);
|
||||
}
|
||||
}
|
||||
#ifndef KNI_DEBUG_TCPREPAIR
|
||||
else
|
||||
{
|
||||
ret=APP_STATE_FAWPKT|APP_STATE_GIVEME;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char kni_data_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const struct ip* ip_hdr)
|
||||
{
|
||||
char ret=APP_STATE_DROPPKT|APP_STATE_GIVEME;
|
||||
|
||||
char* data=NULL;
|
||||
int datalen=0;
|
||||
|
||||
int iplen=ntohs(ip_hdr->ip_len);
|
||||
struct kni_tcp_hdr* tcphdr=(struct kni_tcp_hdr*)((char*)ip_hdr+4*(ip_hdr->ip_hl));
|
||||
|
||||
data=kni_get_data(pstream,&datalen);
|
||||
|
||||
if(pmeinfo->status_flag==KNI_FLAG_UNKNOW)
|
||||
{
|
||||
if((tcphdr->th_flags&TH_SYN)&&(tcphdr->th_flags&TH_ACK))
|
||||
{
|
||||
kni_get_tcpopt(tcphdr,iplen-4*(ip_hdr->ip_hl)-datalen,&(pmeinfo->mss[pstream->curdir-1]),&(pmeinfo->wnscal[pstream->curdir-1]),&(pmeinfo->sack[pstream->curdir-1]),&(pmeinfo->timestamps[pstream->curdir-1]));
|
||||
|
||||
}
|
||||
|
||||
kni_get_tcpinfo(&(pmeinfo->lastpkt_info[pstream->curdir-1]),tcphdr,ntohs(ip_hdr->ip_len)-4*ip_hdr->ip_hl-4*tcphdr->th_off,(struct ip*)ip_hdr);
|
||||
|
||||
if(datalen>0)
|
||||
{
|
||||
ret=kni_first_tcpdata(pstream,ip_hdr,pmeinfo,data,datalen);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret=APP_STATE_FAWPKT|APP_STATE_GIVEME;
|
||||
}
|
||||
}
|
||||
|
||||
if((pmeinfo->status_flag==KNI_FLAG_HTTP)||(pmeinfo->status_flag==KNI_FLAG_SSL))
|
||||
{
|
||||
ret=tun_write_data(g_kni_comminfo.fd_tun[thread_seq],(char*)ip_hdr,iplen,(struct streaminfo*)pstream,thread_seq);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
char kni_close_opstate(const struct streaminfo* pstream,struct kni_pme_info* pmeinfo,int thread_seq,const struct ip* ip_hdr)
|
||||
{
|
||||
|
||||
char ret=APP_STATE_FAWPKT|APP_STATE_DROPME;
|
||||
|
||||
if(ip_hdr==NULL)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret=kni_data_opstate(pstream,pmeinfo,thread_seq,ip_hdr);
|
||||
|
||||
return ret|APP_STATE_DROPME;
|
||||
}
|
||||
|
||||
|
||||
extern "C" char kni_tcpall_entry(const struct streaminfo* pstream,void** pme,int thread_seq,const void* ip_hdr)
|
||||
{
|
||||
|
||||
char ret=APP_STATE_FAWPKT|APP_STATE_DROPME;
|
||||
if((g_kni_comminfo.kni_mode_cur==KNI_MODE_BYPASS)||(pstream->addr.addrtype==ADDR_TYPE_IPV6))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
kni_filestate2_set(thread_seq,FS2_COLUME_RECV,0,1);
|
||||
|
||||
|
||||
switch(pstream->pktstate)
|
||||
{
|
||||
case OP_STATE_PENDING:
|
||||
kni_init_pmeinfo(pme);
|
||||
ret=kni_pending_opstate(pstream,(struct kni_pme_info*)*pme,thread_seq,(const struct ip*)ip_hdr,PROTO_TYPE_TCP);
|
||||
break;
|
||||
|
||||
case OP_STATE_DATA:
|
||||
ret=kni_data_opstate(pstream,(struct kni_pme_info*)*pme,thread_seq,(const struct ip*)ip_hdr);
|
||||
break;
|
||||
|
||||
case OP_STATE_CLOSE:
|
||||
ret=kni_close_opstate(pstream,(struct kni_pme_info*)*pme,thread_seq,(const struct ip*)ip_hdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if((ret&APP_STATE_DROPME)&&(*pme!=NULL))
|
||||
{
|
||||
kni_free_pmeinfo(pme);
|
||||
*pme=NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
extern "C" char kni_http_entry(stSessionInfo* session_info, void **pme, int thread_seq,struct streaminfo *a_stream,const void *a_packet)
|
||||
{
|
||||
char ret=PROT_STATE_DROPME;
|
||||
|
||||
int host_len=session_info->buflen>KNI_DEFAULT_MTU?KNI_DEFAULT_MTU:session_info->buflen;
|
||||
struct kni_http_project* host_info=(struct kni_http_project*)malloc(sizeof(struct kni_http_project));
|
||||
host_info->host_len=host_len;
|
||||
memcpy(host_info->host,session_info->buf,host_len);
|
||||
|
||||
project_req_add_struct(a_stream,g_kni_comminfo.project_id,host_info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void kni_free_project(int thread_seq, void *project_req_value)
|
||||
{
|
||||
free(project_req_value);
|
||||
project_req_value=NULL;
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int kni_read_cardname()
|
||||
{
|
||||
int offset=0;
|
||||
char* token=NULL;
|
||||
char buf[KNI_CONF_MAXLEN]={0};
|
||||
|
||||
int routdir=0;
|
||||
|
||||
FILE* fp=fopen("./conf/send_raw_pkt.conf","r");
|
||||
if(fp==NULL)
|
||||
{
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"kni_read_cardname","fopen ./conf/send_raw_pkt.conf err,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(feof(fp)==0)
|
||||
{
|
||||
routdir=0;
|
||||
memset(buf,0,KNI_CONF_MAXLEN);
|
||||
|
||||
if((fgets(buf,KNI_CONF_MAXLEN,fp)==NULL))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(buf[0]=='#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
token=strtok(buf,"\t, ");
|
||||
offset=1;
|
||||
|
||||
while(token!=NULL)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case KNI_OFFSET_ROUTDIR:
|
||||
routdir=atoi(token);
|
||||
if((routdir!=0)&&(routdir!=1))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"kni_read_cardname","routdir :%d error",routdir);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case KNI_OFFSET_CARDNAME:
|
||||
memcpy(g_kni_cardname[routdir],token,strlen(token));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
token=strtok(NULL,"\t, ");
|
||||
offset++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
fp=NULL;
|
||||
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"kni_read_cardname","card name:%s,%s",g_kni_cardname[0],g_kni_cardname[1]);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int init_profile_info()
|
||||
{
|
||||
//main.conf
|
||||
// MESA_load_profile_int_def((char*)KNI_CONF_FILENAME_MAIN,(char*)KNI_CONF_MODE,(char*)"thread_num",&(g_kni_comminfo.thread_num),1);
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME_MAIN,(char*)KNI_CONF_MODE,(char*)"pcapdevice",g_kni_comminfo.card_in,KNI_CONF_MAXLEN,"cap0");
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME_MAIN,(char*)KNI_CONF_MODE,(char*)"pcapdevice2",g_kni_comminfo.card_out,KNI_CONF_MAXLEN,"cap1");
|
||||
|
||||
|
||||
//kni.conf
|
||||
MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"replay_win_update",&(g_kni_switch_info.replay_win_update),1);
|
||||
MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"default_work_mode",&(g_kni_switch_info.maat_default_mode),KNI_DEFAULT_MODE_INTERCEPT);
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"tun_name",g_kni_comminfo.tun_name,KNI_CONF_MAXLEN,"tun0");
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"domain_path",g_kni_comminfo.domain_path,KNI_CONF_MAXLEN,"/home/server_unixsocket_file");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int init_kni_stat_htable()
|
||||
{
|
||||
MESA_htable_create_args_t hash_frags;
|
||||
|
||||
memset(&hash_frags,0,sizeof(MESA_htable_create_args_t));
|
||||
|
||||
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_to_tun_v4=MESA_htable_create(&hash_frags,sizeof(MESA_htable_create_args_t));
|
||||
g_kni_structinfo.htable_to_tun_v6=MESA_htable_create(&hash_frags,sizeof(MESA_htable_create_args_t));
|
||||
if((g_kni_structinfo.htable_to_tun_v4==NULL)||(g_kni_structinfo.htable_to_tun_v6==NULL))
|
||||
{
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"MESA_htable_create() error!action:%s",KNI_ACTION_EXIT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int init_kni_runtimelog()
|
||||
{
|
||||
int logger_level;
|
||||
char logger_filepath[KNI_CONF_MAXLEN]={0};
|
||||
|
||||
|
||||
MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"logger_level",&logger_level,RLOG_LV_INFO);
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"logger_filepath",logger_filepath,KNI_CONF_MAXLEN,"./log/kni.log");
|
||||
|
||||
|
||||
g_kni_comminfo.logger=MESA_create_runtime_log_handle(logger_filepath,logger_level);
|
||||
if(g_kni_comminfo.logger==NULL)
|
||||
{
|
||||
printf("MESA_create_runtime_log_handle() error!exit...\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int init_kni_maat_info()
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
int maat_readconf_mode=0;
|
||||
int redis_db_index=0;
|
||||
int redis_port=0;
|
||||
unsigned short redis_port_real=0;
|
||||
char redis_ip[INET_ADDRSTRLEN]={0};
|
||||
int scandir_interval=KNI_SCANDIR_INTERVAL;
|
||||
int effect_interval=KNI_EFFECT_INTERVAL;
|
||||
|
||||
char table_info_path[KNI_CONF_MAXLEN]={0};
|
||||
char stat_file_dir[KNI_CONF_MAXLEN]={0};
|
||||
char full_cfg_dir[KNI_CONF_MAXLEN]={0};
|
||||
char inc_cfg_dir[KNI_CONF_MAXLEN]={0};
|
||||
|
||||
|
||||
MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"maat_readconf_mode",&maat_readconf_mode,KNI_READCONF_IRIS);
|
||||
MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"scandir_interval",&scandir_interval,KNI_SCANDIR_INTERVAL);
|
||||
MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"effect_interval",&effect_interval,KNI_EFFECT_INTERVAL);
|
||||
MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"redis_db_index",&redis_db_index,0);
|
||||
MESA_load_profile_int_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"redis_port",(int*)&redis_port);
|
||||
|
||||
MESA_load_profile_string_nodef((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"redis_server",redis_ip,INET_ADDRSTRLEN);
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"table_info_path",table_info_path,KNI_CONF_MAXLEN,KNI_TABLEINFO_PATH);
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"inc_cfg_dir",inc_cfg_dir,KNI_CONF_MAXLEN,KNI_INCCFG_FILEPATH);
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"stat_file_path",stat_file_dir,KNI_CONF_MAXLEN,KNI_STAT_FILEPATH);
|
||||
MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"full_cfg_dir",full_cfg_dir,KNI_CONF_MAXLEN,KNI_FULLCFG_FILEPATH);
|
||||
|
||||
|
||||
g_kni_maatinfo.maat_feather=Maat_feather(g_iThreadNum,table_info_path,g_kni_comminfo.logger);
|
||||
if(g_kni_maatinfo.maat_feather==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"Maat_feather() error!table_info_path:%s,action:%s",table_info_path,KNI_ACTION_EXIT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(maat_readconf_mode==KNI_READCONF_JSON)
|
||||
{
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_JSON_FILE_PATH, KNI_MAATJSON_FILEPATH,strlen(KNI_MAATJSON_FILEPATH));
|
||||
}
|
||||
else if(maat_readconf_mode==KNI_READCONF_IRIS)
|
||||
{
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_FULL_CFG_DIR,full_cfg_dir,strlen(full_cfg_dir));
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_INC_CFG_DIR,inc_cfg_dir,strlen(inc_cfg_dir));
|
||||
}
|
||||
else if(maat_readconf_mode==KNI_READCONF_REDIS)
|
||||
{
|
||||
redis_port_real=(unsigned short)redis_port;
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_REDIS_IP,(void*)redis_ip,strlen(redis_ip)+1);
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_REDIS_PORT,(void*)&redis_port_real,sizeof(unsigned short));
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_REDIS_INDEX,(void*)&redis_db_index,sizeof(int));
|
||||
|
||||
}
|
||||
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_SCANDIR_INTERVAL_MS, (void*)&scandir_interval,sizeof(int));
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_EFFECT_INVERVAL_MS, (void*)&effect_interval,sizeof(int));
|
||||
Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_STAT_FILE_PATH,stat_file_dir,strlen(stat_file_dir));
|
||||
|
||||
ret=Maat_initiate_feather(g_kni_maatinfo.maat_feather);
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"Maat_initiate_feather() error!action:%s",KNI_ACTION_EXIT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
if((g_kni_maatinfo.tableid_ip<0)||(g_kni_maatinfo.tableid_domain<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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int init_kni_project()
|
||||
{
|
||||
g_kni_comminfo.project_id=project_producer_register(KNI_PROJECT_NAME,PROJECT_VAL_TYPE_STRUCT,kni_free_project);
|
||||
if(g_kni_comminfo.project_id<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"project_producer_register() error!project_id:%d",g_kni_comminfo.project_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_kni_comminfo.project_id=project_customer_register(KNI_PROJECT_NAME,PROJECT_VAL_TYPE_STRUCT);
|
||||
if(g_kni_comminfo.project_id<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"project_customer_register() error!project_id:%d",g_kni_comminfo.project_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int init_kni_sendpkt()
|
||||
{
|
||||
int i=0;
|
||||
pthread_t pid_read_tun;
|
||||
|
||||
kni_read_cardname();
|
||||
|
||||
g_kni_comminfo.ipv4_fd=(int*)malloc(g_kni_comminfo.thread_num*sizeof(int));
|
||||
for(i=0;i<g_kni_comminfo.thread_num;i++)
|
||||
{
|
||||
g_kni_comminfo.ipv4_fd[i]=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_IP));
|
||||
if(g_kni_comminfo.ipv4_fd[i]<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"ipv4_raw_socket error,i:%d,action:%s",i,KNI_ACTION_EXIT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_kni_threadseq[i]=i;
|
||||
|
||||
pthread_create(&pid_read_tun,NULL,kni_read_tun,&(g_kni_threadseq[i]));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" char kni_init()
|
||||
{
|
||||
int ret=0;
|
||||
|
||||
pthread_t pid_kni_filestat2;
|
||||
|
||||
inet_aton((const char *)&LOCAL_IP_ADDR,(struct in_addr*)&g_kni_comminfo.local_ip);
|
||||
|
||||
init_profile_info();
|
||||
|
||||
ret=init_kni_runtimelog();
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = init_kni_project();
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = init_kni_maat_info();
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret=init_kni_stat_htable();
|
||||
if(ret<0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_kni_structinfo.lqueue_for_domain=MESA_lqueue_create(KNI_THREAD_SAFE,KNI_LQUEUE_MAXNUM);
|
||||
if(g_kni_structinfo.lqueue_for_domain==NULL)
|
||||
{
|
||||
printf("MESA_lqueue_create() error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ret = init_kni_tun();
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
init_kni_domain();
|
||||
|
||||
|
||||
ret = init_kni_sendpkt();
|
||||
if(ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_create(&pid_kni_filestat2,NULL,kni_filestat2,NULL);
|
||||
|
||||
if(g_kni_switch_info.maat_default_mode==0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"default work module is intercept");
|
||||
}
|
||||
else if(g_kni_switch_info.maat_default_mode==1)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"default work module is bypass");
|
||||
}
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"kni init succ!");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
#ifndef KNI_PROCESS_H
|
||||
#define KNI_PROCESS_H
|
||||
|
||||
|
||||
#include "stream.h"
|
||||
#include "MESA_prof_load.h"
|
||||
#include "MESA_handle_logger.h"
|
||||
#include "MESA_htable.h"
|
||||
#include "MESA_list_queue.h"
|
||||
#include "field_stat2.h"
|
||||
#include "Maat_rule.h"
|
||||
#include "kni_comm.h"
|
||||
#include "kni_connect.h"
|
||||
#include "kni_repair.h"
|
||||
|
||||
|
||||
#ifndef TH_FIN
|
||||
#define TH_FIN 0x01
|
||||
#endif
|
||||
@@ -157,24 +170,8 @@
|
||||
#define KNI_DEFAULT_MODE_INTERCEPT 0
|
||||
#define KNI_DEFAULT_MODE_BYPASS 1
|
||||
|
||||
//filestate2
|
||||
#define FS2_COLUMN_NUM 9
|
||||
#define FS2_APPNAME "KNI"
|
||||
|
||||
|
||||
enum kni_FS_COLUME
|
||||
{
|
||||
FS2_COLUME_RECV=0,
|
||||
FS2_COLUME_WRITE,
|
||||
FS2_COLUME_READ,
|
||||
FS2_COLUME_SEND,
|
||||
FS2_COLUME_WITELIST_IP,
|
||||
FS2_COLUME_WITELIST_DOMAIN,
|
||||
FS2_COLUME_HTTP,
|
||||
FS2_COLUME_SSL,
|
||||
FS2_COLUME_DROPPKT,
|
||||
};
|
||||
|
||||
|
||||
enum kni_flag
|
||||
{
|
||||
@@ -260,14 +257,6 @@ struct kni_var_maat
|
||||
short tableid_domain;
|
||||
};
|
||||
|
||||
//field stat2
|
||||
struct kni_fs2_info
|
||||
{
|
||||
screen_stat_handle_t handler;
|
||||
int column_id[FS2_COLUMN_NUM];
|
||||
unsigned long long column_value_pkt[KNI_MAX_THREADNUM][FS2_COLUMN_NUM];
|
||||
unsigned long long column_value_bytes[KNI_MAX_THREADNUM][FS2_COLUMN_NUM];
|
||||
};
|
||||
|
||||
struct kni_tlv_info
|
||||
{
|
||||
@@ -412,5 +401,17 @@ struct tcp_repair_window {
|
||||
*/
|
||||
|
||||
|
||||
|
||||
extern struct kni_var_comm g_kni_comminfo;
|
||||
extern struct kni_var_struct g_kni_structinfo;
|
||||
extern struct kni_var_maat g_kni_maatinfo;
|
||||
extern struct kni_fs2_info g_kni_fs2_info;
|
||||
extern struct kni_switch_info g_kni_switch_info;
|
||||
|
||||
|
||||
extern int g_iThreadNum;
|
||||
extern char g_kni_cardname[KNI_CARD_NUM][KNI_CONF_MAXLEN];
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
275
kni_repair.c
Normal file
275
kni_repair.c
Normal file
@@ -0,0 +1,275 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "kni_entry.h"
|
||||
|
||||
|
||||
|
||||
int tcprepair_get_state(struct kni_tcp_state* fake_client,struct kni_tcp_state* fake_server,void* a_packet,struct kni_pme_info* pmeinfo)
|
||||
{
|
||||
|
||||
struct ip* iphdr=(struct ip*)a_packet;
|
||||
struct tcphdr* tcphdr=(struct tcphdr*)((char*)a_packet+4*(iphdr->ip_hl));
|
||||
|
||||
fake_client->src_ip=(iphdr->ip_src).s_addr;
|
||||
fake_client->sport=tcphdr->source;
|
||||
fake_client->dst_ip=(iphdr->ip_dst).s_addr;
|
||||
fake_client->dport =tcphdr->dest;
|
||||
fake_client->seq=ntohl(tcphdr->seq);
|
||||
fake_client->ack=ntohl(tcphdr->ack_seq);
|
||||
fake_client->mss_src=pmeinfo->mss[KNI_DIR_C2S];
|
||||
fake_client->mss_dst=pmeinfo->mss[KNI_DIR_S2C];
|
||||
fake_client->wscale_src=pmeinfo->wnscal[KNI_DIR_C2S];
|
||||
fake_client->wscale_dst=pmeinfo->wnscal[KNI_DIR_S2C];
|
||||
fake_client->sack_src=pmeinfo->sack[KNI_DIR_C2S];
|
||||
fake_client->sack_dst=pmeinfo->sack[KNI_DIR_S2C];
|
||||
fake_client->timestamps_src=pmeinfo->timestamps[KNI_DIR_C2S];
|
||||
fake_client->timestamps_dst=pmeinfo->timestamps[KNI_DIR_S2C];
|
||||
|
||||
fake_server->src_ip=(iphdr->ip_dst).s_addr;
|
||||
fake_server->sport=tcphdr->dest;
|
||||
fake_server->dst_ip=(iphdr->ip_src).s_addr;
|
||||
fake_server->dport =tcphdr->source;
|
||||
fake_server->seq=ntohl(tcphdr->ack_seq);
|
||||
fake_server->ack=ntohl(tcphdr->seq);
|
||||
fake_server->mss_src=pmeinfo->mss[KNI_DIR_S2C];
|
||||
fake_server->mss_dst=pmeinfo->mss[KNI_DIR_C2S];
|
||||
fake_server->wscale_src=pmeinfo->wnscal[KNI_DIR_S2C];
|
||||
fake_server->wscale_dst=pmeinfo->wnscal[KNI_DIR_C2S];
|
||||
fake_server->sack_src=pmeinfo->sack[KNI_DIR_S2C];
|
||||
fake_server->sack_dst=pmeinfo->sack[KNI_DIR_C2S];
|
||||
fake_server->timestamps_src=pmeinfo->timestamps[KNI_DIR_S2C];
|
||||
fake_server->timestamps_dst=pmeinfo->timestamps[KNI_DIR_C2S];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tcprepair_set_state(int sk,struct kni_tcp_state* tcp)
|
||||
{
|
||||
int val,yes=1, onr = 0;
|
||||
// int mark = 2;
|
||||
// int mark_tmp=0;
|
||||
// socklen_t mark_len=sizeof(mark_tmp);
|
||||
struct tcp_repair_opt opts[KNI_TCPREPAIR_OPT_NUM];
|
||||
struct sockaddr_in addr;
|
||||
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR, &yes, sizeof(yes))==-1)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (setsockopt(sk, SOL_IP, IP_TRANSPARENT, &yes, sizeof(yes)) < 0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() IP_TRANSPARENT error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() SO_REUSEADDR error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
if(setsockopt(sk, SOL_SOCKET, SO_MARK, &mark, sizeof(mark))<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() SO_MARK error,errno:%d",errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
getsockopt(sk, SOL_SOCKET, SO_MARK, &mark_tmp, &mark_len);
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","getsockopt() SO_MARK :%d",mark_tmp);
|
||||
*/
|
||||
/* ============= Restore TCP properties ==================*/
|
||||
val = TCP_SEND_QUEUE;
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR_QUEUE, &val, sizeof(val)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR_QUEUE,TCP_SEND_QUEUE error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = tcp->seq;
|
||||
if (setsockopt(sk, SOL_TCP, TCP_QUEUE_SEQ, &val, sizeof(val)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = TCP_RECV_QUEUE;
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR_QUEUE, &val, sizeof(val)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR_QUEUE,TCP_RECV_QUEUE error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = tcp->ack;
|
||||
if (setsockopt(sk, SOL_TCP, TCP_QUEUE_SEQ, &val, sizeof(val)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
struct tcp_repair_window win;
|
||||
|
||||
win.snd_wl1=tcp->seq;
|
||||
win.snd_wnd=tcp->wnscale[KNI_DIR_C2S]<<tcp->wnscale[KNI_DIR_S2C];
|
||||
win.max_window=win.snd_wnd;
|
||||
win.rcv_wnd=win.snd_wnd;
|
||||
win.rcv_wup=win.snd_wl1;
|
||||
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR_WINDOW, &win, sizeof(win)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR_WINDOW error,errno:%d",errno);
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
/* ============= Bind and connect ================ */
|
||||
memset(&addr,0,sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = tcp->sport;
|
||||
addr.sin_addr.s_addr=tcp->src_ip;
|
||||
|
||||
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","bind() error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&addr,0,sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = tcp->dport;
|
||||
addr.sin_addr.s_addr=tcp->dst_ip;
|
||||
|
||||
if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","connect() error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
opts[onr].opt_code = TCPOPT_WINDOW;
|
||||
opts[onr].opt_val = tcp->wscale_src+ (tcp->wscale_dst<< 16);
|
||||
onr++;
|
||||
*/
|
||||
|
||||
|
||||
if((tcp->wscale_dst)&&(tcp->wscale_src))
|
||||
{
|
||||
opts[onr].opt_code = TCPOPT_WINDOW;
|
||||
opts[onr].opt_val = tcp->wscale_dst+ (tcp->wscale_src<< 16);
|
||||
onr++;
|
||||
}
|
||||
|
||||
|
||||
opts[onr].opt_code = TCPOPT_MAXSEG;
|
||||
opts[onr].opt_val = (tcp->mss_src<tcp->mss_dst)?tcp->mss_src:tcp->mss_dst;
|
||||
onr++;
|
||||
|
||||
if((tcp->sack_src)&&(tcp->sack_dst))
|
||||
{
|
||||
opts[onr].opt_code = TCPOPT_SACK_PERMITTED;
|
||||
opts[onr].opt_val = 0;
|
||||
onr++;
|
||||
}
|
||||
/*
|
||||
opts[onr].opt_code = TCPOPT_TIMESTAMP;
|
||||
opts[onr].opt_val = (tcp->timestamps_src)&&(tcp->timestamps_dst);
|
||||
onr++;
|
||||
*/
|
||||
|
||||
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR_OPTIONS,opts, onr * sizeof(struct tcp_repair_opt)) < 0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR_OPTIONS error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = 0;
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR, &val, sizeof(val)))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_REPAIR close error,errno:%d,%s",errno,strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tcp_repair_process(const struct streaminfo* pstream,const struct ip* a_packet,struct kni_pme_info* pmeinfo,int protocol)
|
||||
{
|
||||
#ifdef KNI_DEBUG_TCPREPAIR
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
int ret=0;
|
||||
int fds[KNI_FDS_NUM];
|
||||
int fd_client,fd_server;
|
||||
struct kni_tcp_state fake_client;
|
||||
struct kni_tcp_state fake_server;
|
||||
|
||||
// struct ip* iphdr=(struct ip*)a_packet;
|
||||
// struct tcphdr* tcphdr=(struct tcphdr*)((char*)a_packet+4*(iphdr->ip_hl));
|
||||
// int tcplen=ntohs(iphdr->ip_len)-4*iphdr->ip_hl-4*tcphdr->doff;
|
||||
|
||||
fd_client = socket(AF_INET, SOCK_STREAM, 0);
|
||||
fd_server = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if ((fd_client < 0)||(fd_server<0))
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","socket() error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcprepair_get_state(&fake_client,&fake_server,(void*)a_packet,pmeinfo);
|
||||
|
||||
ret=tcprepair_set_state(fd_client,&fake_server);
|
||||
if(ret<0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","fd_client tcprepair_set_state() error,dropme and fwdpkt");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret=tcprepair_set_state(fd_server,&fake_client);
|
||||
if(ret<0)
|
||||
{
|
||||
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","fd_server tcprepair_set_state() error,dropme and fwdpkt");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
fds[0]=fd_client;
|
||||
fds[1]=fd_server;
|
||||
fds[2]=protocol;
|
||||
|
||||
ret=MESA_lqueue_join_head(g_kni_structinfo.lqueue_for_domain,(void*)fds,KNI_FDS_NUM*sizeof(int));
|
||||
if(ret <0)
|
||||
{
|
||||
MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_SENDFD,"MESA_lqueue_try_join_head() error,ret:%d",ret);
|
||||
}
|
||||
|
||||
/*
|
||||
kni_send_fds(g_kni_comminfo.fd_domain,fds,2,protocol);
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
*/
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
10
kni_repair.h
Normal file
10
kni_repair.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef KNI_REPAIR_H
|
||||
#define KNI_REPAIR_H
|
||||
|
||||
|
||||
int tcp_repair_process(const struct streaminfo* pstream,const struct ip* a_packet,struct kni_pme_info* pmeinfo,int protocol);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user