#include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include "forge_socket.h" #include "stream.h" #include "MESA_prof_load.h" #include "MESA_handle_logger.h" #include "MESA_htable.h" #include "MESA_list_queue.h" #include "Maat_rule.h" #include "kni.h" int g_kni_version_VERSION_20180620; struct kni_var_comm g_kni_comminfo; struct kni_var_struct g_kni_structinfo; struct kni_var_maat g_kni_maatinfo; int g_kni_fds[2]; extern int g_iThreadNum; 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); /******************************************************************************************************************** name: function: return: *********************************************************************************************************************/ int kni_debug_info_v4(char* module,int state_flag,struct ip* a_packet) { // return 0; struct timeval cur_time; int iplen=ntohs(a_packet->ip_len); struct tcphdr* tcphdr=(struct tcphdr*)((char*)a_packet+4*(a_packet->ip_hl)); unsigned int seq=ntohl(tcphdr->seq); unsigned int ack=ntohl(tcphdr->ack_seq); 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); gettimeofday(&cur_time,NULL); MESA_handle_runtime_log(g_kni_comminfo.logger,RLOG_LV_DEBUG,module,"addr:%s,%d,%s,%d,state_flag:%d,ip_len:%d,seq:%u,ack:%u,tv_sec:%lu,tv_usec:%lu",saddr_v4,sport,daddr_v4,dport,state_flag,iplen,seq,ack,cur_time.tv_sec,cur_time.tv_usec); return 0; } /**************************************************************************** if(sportip_hl)); sport=ntohs(tcphdr->source); dport=ntohs(tcphdr->dest); if((sportip_src).s_addr)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(sportsource); dport=ntohs(tcphdr->dest); if(sportsaddr,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; } static void kni_send_fds(int socket, int *fds, int n) // send fd by socket { struct msghdr msg = {0}; struct cmsghdr *cmsg; char buf[CMSG_SPACE(n * sizeof(int))], dup[256]; memset(buf, 0, sizeof(buf)); struct iovec io = { .iov_base = &dup, .iov_len = sizeof(dup) }; 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) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"kni_send_fds","sendmsg()error,errno:%d",errno); return; } return; } 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; 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; ifr.ifr_flags = IFF_TUN | IFF_NO_PI; 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,action:%s",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,action:%s",errno,KNI_ACTION_EXIT); close(fd); tun_error(i,fds); return -1; } fds[i] = fd; } return 0; } int tun_alloc(char *dev, int flags) { struct ifreq ifr; int fd, err; char *clonedev = (char*)"/dev/net/tun"; /* open the clone device */ if( (fd = open(clonedev, O_RDWR)) < 0 ) { return fd; } /* preparation of the struct ifr, of type "struct ifreq" */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */ if (*dev) { strncpy(ifr.ifr_name, dev, IFNAMSIZ); } /* try to create the device */ if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) { close(fd); return err; } strcpy(dev, ifr.ifr_name); return fd; } /******************************************************************************************************************** name: function: args: return: *********************************************************************************************************************/ int tun_read_data(int fd,char* recv_buf,int max_buflen) { int recv_len=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_READTUN,"tun_read_data error,msg is: %s\n",strerror(errno)); } return recv_len; } /******************************************************************************************************************** name: function: return: *********************************************************************************************************************/ int tun_write_data(int fd,char* send_buf,int send_buflen,struct stream_tuple4_v4* ipv4_addr) { 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_sendlenwin; unsigned short win_scale=datainfo->wnscal[1]; unsigned short ipid=random()%65535; struct ip* iphdr=(struct ip*)a_packet; struct tcphdr* tcphdr=(struct tcphdr*)((char*)iphdr+4*(iphdr->ip_hl)); 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=htons(datainfo->ipid[index]+1); // snd_iphdr->ip_ttl=datainfo->ttl[index]; snd_tcphdr->source=tcphdr->dest; snd_tcphdr->dest=tcphdr->source; snd_tcphdr->seq=htonl(datainfo->seq[index]+datainfo->len[index]); snd_tcphdr->ack_seq=htonl(datainfo->ack[index]); /* 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,ipv4_addr); kni_debug_info_v4((char*)"recv_keepalive_request",STAT_FLAG_SSL_NOBMD,(struct ip*)a_packet); kni_debug_info_v4((char*)"send_keepalive_replay",STAT_FLAG_SSL_NOBMD,(struct ip*)sendbuf); free(sendbuf); sendbuf=NULL; datainfo->pro_reply[iprever_flag]=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 datainfo_to_tun* ret_data=(struct datainfo_to_tun*)user_arg; struct datainfo_to_tun* datainfo=(struct datainfo_to_tun*)data; if(datainfo!=NULL) { // memcpy(ret_data,datainfo,sizeof(struct datainfo_to_tun)); memcpy(args->smac,datainfo->smac,KNI_MACADDR_LEN); memcpy(args->dmac,datainfo->dmac,KNI_MACADDR_LEN); if(datainfo->pro_reply[args->iprevers]>0) { result=1; } else { kni_keepalive_replay(ipv4_addr,args->iprevers,datainfo,args->a_packet,args->iplen,args->thread_seq); result=0; } } /* #ifdef KNI_DEBUG_SWITCH else if(ipv4_addr->saddr==1698867392) { printf("sip is 192.168.66.101\n"); ret_data->route_dir=0; ret_data->smac[0]=0x18; ret_data->smac[1]=0x66; ret_data->smac[2]=0xda; ret_data->smac[3]=0xe5; ret_data->smac[4]=0xfa; ret_data->smac[5]=0xa1; ret_data->dmac[0]=0xe8; ret_data->dmac[1]=0x61; ret_data->dmac[2]=0x1f; ret_data->dmac[3]=0x13; ret_data->dmac[4]=0x70; ret_data->dmac[5]=0x7a; result=0; } #endif */ return result; } int kni_process_readdata(int thread_seq,int buflen,char* buf) { int ret; int iprever_flag=0; long result=0; // struct datainfo_to_tun datainfo; struct args_read_tun args; struct ip* iphdr=(struct ip*)buf; struct stream_tuple4_v4 ipv4_addr; struct stream_tuple4_v6 ipv6_addr; if(iphdr->ip_v==4) { iprever_flag=kni_get_ipaddr_v4((void*)buf,&ipv4_addr); kni_debug_info_v4((char*)KNI_MODULE_READTUN,STAT_FLAG_SSL_NOBMD,(struct ip*)buf); 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.smac,args.dmac); } } else { iprever_flag=kni_get_ipaddr_v6((void*)buf,&ipv6_addr); } return 0; } /******************************************************************************************************************** name: function: return: *********************************************************************************************************************/ void* kni_read_tun(void* arg) { int i=0; int recv_len=0; char recv_buf[KNI_MAX_BUFLEN] = {0}; while(1) { for(i=0;itstamp_ok = 0; st->sack_ok = 0; st->wscale_ok = 0; st->ecn_ok = 0; // st->snd_wscale = 0; // st->rcv_wscale = 0; st->snd_wscale = 128; st->rcv_wscale = 128; st->snd_wnd = 0x1000; st->rcv_wnd = 0x1000; st->inet_ttl=-1; //make sure you set snd_una = seq (TODO: fix this in module) return st; } /******************************************************************************************************************** name: function: return: *********************************************************************************************************************/ int fs_set_state(int sock, struct tcp_state *st) { struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_addr.s_addr = st->src_ip; sin.sin_port = st->sport; st->snd_una = st->seq; int value = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) < 0) { perror("setsockopt SO_REUSEADDR"); return -1; } if (setsockopt(sock, SOL_IP, IP_TRANSPARENT, &value, sizeof(value)) < 0) { perror("setsockopt IP_TRANSPARENT"); return -1; } if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("bind"); return -1; } if (setsockopt(sock, IPPROTO_TCP, TCP_STATE, st, sizeof(struct tcp_state)) < 0) { perror("setsockopt TCP_STATE"); return -1; } return 0; } //default:a_packet is c2s; /******************************************************************************************************************** name: function: return: *********************************************************************************************************************/ int fs_get_modify_state(struct tcp_state* fake_client,struct tcp_state* fake_server,void* a_packet,unsigned int mss) { 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->snd_una = fake_client->seq; fake_client->snd_wnd = 0x1000; fake_client->rcv_wnd = 0x1000; fake_client->mss_clamp=mss; 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->snd_una = fake_server->seq; fake_server->snd_wnd = 0x1000; fake_server->rcv_wnd = 0x1000; fake_server->mss_clamp=mss; return 0; } /******************************************************************************************************************** name:kni_process_fs() function: return: 0:succ -1:error *********************************************************************************************************************/ int kni_process_fs(void* a_packet,unsigned int mss) { int fds[2]={0}; fds[KNI_FDS_INDEX_CLIENT]=socket(AF_INET, SOCK_FORGE, 0); fds[KNI_FDS_INDEX_SERVER]=socket(AF_INET, SOCK_FORGE, 0); if (fds[KNI_FDS_INDEX_CLIENT] < 0 || fds[KNI_FDS_INDEX_SERVER]< 0) { perror("SOCK_FORGE socket"); fprintf(stderr, "(Did you insmod forge_socket.ko?)\n"); return -1; } struct tcp_state* fake_client=fs_get_default_state(); struct tcp_state* fake_server=fs_get_default_state(); fs_get_modify_state(fake_client,fake_server,a_packet,mss); fs_set_state(fds[KNI_FDS_INDEX_CLIENT],fake_server); fs_set_state(fds[KNI_FDS_INDEX_SERVER],fake_client); kni_send_fds(g_kni_comminfo.fd_domain,fds,2); // kni_debug_info_v4((char*)KNI_MODULE_SENDFD,STAT_FLAG_SSL_NOBMD,(struct ip*)a_packet); close(fds[KNI_FDS_INDEX_CLIENT]); close(fds[KNI_FDS_INDEX_SERVER]); return 0; } int tcprepair_set_state_bak(int sk,struct kni_state_info* tcp) { int val,yes=1, onr = 0; int src=KNI_INDEX_SRC; int dst=KNI_INDEX_DST; 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"); 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"); return -1; } /* ============= 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"); return -1; } val = tcp[src].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"); 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"); return -1; } val = tcp[dst].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"); return -1; } /* ============= Bind and connect ================ */ memset(&addr,0,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(tcp[src].port); if (inet_pton(AF_INET, tcp[src].addr, &(addr.sin_addr)) < 0) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error"); return -1; } if (bind(sk, (struct sockaddr *) &addr, sizeof(addr))) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error"); return -1; } memset(&addr,0,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(tcp[dst].port); if (inet_pton(AF_INET, tcp[dst].addr, &(addr.sin_addr)) < 0) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error"); return -1; } if (connect(sk, (struct sockaddr *) &addr, sizeof(addr))) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","setsockopt() TCP_QUEUE_SEQ error"); return -1; } opts[onr].opt_code = TCPOPT_WINDOW; opts[onr].opt_val = tcp[src].wscale + (tcp[dst].wscale << 16); onr++; opts[onr].opt_code = TCPOPT_MAXSEG; opts[onr].opt_val = tcp[src].mss_clamp; 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_QUEUE_SEQ error"); return -1; } return 0; } int tcprepair_set_state(int sk,struct kni_tcp_state* tcp,struct tcp_repair_window win) { int val,yes=1, onr = 0; 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",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",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",errno); return -1; } /* ============= 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",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",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",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",errno); return -1; } /* 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; } //test // MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","snd_wl1:%u,snd_wnd:%u,max_wnd:%u,rcv_wnd:%u,rcv_wup:%u",win.snd_wl1,win.snd_wnd,win.max_window,win.rcv_wnd,win.rcv_wup); struct tcp_repair_window win_tmp; socklen_t opt_len=sizeof(win_tmp); if (getsockopt(sk, SOL_TCP, TCP_REPAIR_WINDOW, &win_tmp,&opt_len)) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","getsockopt() TCP_REPAIR_WINDOW error,errno:%d",errno); return -1; } MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,"tcprepair_set_state","snd_wl1:%u,snd_wnd:%u,max_wnd:%u,rcv_wnd:%u,rcv_wup:%u",win_tmp.snd_wl1,win_tmp.snd_wnd,win_tmp.max_window,win_tmp.rcv_wnd,win_tmp.rcv_wup); //end */ /* ============= 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; // addr.sin_addr.s_addr= g_kni_comminfo.local_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",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",errno); return -1; } opts[onr].opt_code = TCPOPT_WINDOW; opts[onr].opt_val = tcp->wscale_src+ (tcp->wscale_dst<< 16); onr++; opts[onr].opt_code = TCPOPT_MAXSEG; opts[onr].opt_val = tcp->mss_src; 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",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",errno); return -1; } return 0; } int tcprepair_get_state(struct kni_tcp_state* fake_client,struct kni_tcp_state* fake_server,void* a_packet,unsigned short* mss,unsigned short* wnscale,unsigned short win) { 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->win=ntohs(tcphdr->window); fake_client->win=win; fake_client->mss_src=mss[KNI_INDEX_SRC]; fake_client->mss_dst=mss[KNI_INDEX_DST]; fake_client->wscale_src=wnscale[KNI_INDEX_SRC]; fake_client->wscale_dst=wnscale[KNI_INDEX_DST]; 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->win=ntohs(tcphdr->window); fake_server->mss_src=mss[KNI_INDEX_DST]; fake_server->mss_dst=mss[KNI_INDEX_SRC]; fake_server->wscale_src=wnscale[KNI_INDEX_DST]; fake_server->wscale_dst=wnscale[KNI_INDEX_SRC]; return 0; } int kni_process_tcprepair(void* a_packet,unsigned short* mss,unsigned short* wnscale,unsigned short win) { int fds[2]; 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; struct tcp_repair_window fclient_win; struct tcp_repair_window fserver_win; 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,a_packet,mss,wnscale,win); fserver_win.snd_wl1=ntohl(tcphdr->seq); fserver_win.snd_wnd=ntohs(tcphdr->window)<seq); fclient_win.snd_wl1=ntohl(tcphdr->ack_seq)-1; fclient_win.snd_wnd=win; fclient_win.max_window=fclient_win.snd_wnd; fclient_win.rcv_wnd=ntohs(tcphdr->window)<ack_seq); /* //c has get fclient_win.snd_wl1=ntohl(tcphdr->ack_seq); fclient_win.snd_wnd=ntohs(tcphdr->window)<0) { state_flag=STAT_FLAG_SNIBMD; } return state_flag; } /*************************************************************************************** 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 state_flag=STAT_FLAG_NONE; return STAT_FLAG_SSL_NOBMD; 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 STAT_FLAG_NOTSSL; } 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 STAT_FLAG_NOTSSL; } 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 STAT_FLAG_NOTSSL; } 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 STAT_FLAG_NOTSSL; } 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 STAT_FLAG_NOTSSL; } 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 STAT_FLAG_NOTSSL; } 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 STAT_FLAG_NOTSSL; } ssl_extention_len+=2; while(ssl_extention_lenKNI_SNI_MAXLEN) { //error return STAT_FLAG_NOTSSL; } memcpy(sni,&ssl_extention[ssl_extention_len],len_in_extension); *sni_len=len_in_extension; return STAT_FLAG_SSL_NOBMD; } else { ssl_extention_len+=len_in_extension; continue; } } return STAT_FLAG_NOTSSL; } /*************************************************************************************** return :state_flag ipbmd:STAT_FLAG_IPBMD not ipbmd:STAT_FLAG_NONE ***************************************************************************************/ int kni_judge_ipbmd(struct ipaddr* addr,int thread_seq) { int state_flag=STAT_FLAG_NONE; int ipscan_num=0; scan_status_t mid=NULL; struct Maat_rule_t maat_result[KNI_MAX_CFGNUM]; ipscan_num=Maat_scan_proto_addr(g_kni_maatinfo.maat_feather,g_kni_maatinfo.tableid_ipbmd,addr,PROTO_TYPE_TCP,maat_result,KNI_MAX_CFGNUM,&mid,thread_seq); Maat_clean_status(&mid); if(ipscan_num>0) { state_flag=STAT_FLAG_IPBMD; } return state_flag; } int kni_get_mss(struct kni_tcp_hdr* tcphdr,int tcp_hdr_len,unsigned short* mss,unsigned char* winscale) { // unsigned short mss=KNI_DEFAULT_MSS; *mss=KNI_DEFAULT_MSS; *winscale=KNI_DEFAULT_WINSCLE; // return 0; int remain_len=tcp_hdr_len; struct kni_tcp_opt* tcp_opt=NULL; if((tcp_hdr_len<=20)||(tcp_hdr_len>64)) { return 0; } tcp_opt=(struct kni_tcp_opt*)((char*)tcphdr+TCPHDR_DEFAULT_LEN); remain_len-=TCPHDR_DEFAULT_LEN; while(remain_len) { if(tcp_opt->type==2) //MSS { remain_len-=tcp_opt->len; *mss=htons(*(unsigned short*)(tcp_opt->content)); tcp_opt=(struct kni_tcp_opt*)((char*)tcp_opt+tcp_opt->len); } else if(tcp_opt->type==3) //winscale { remain_len-=tcp_opt->len; *winscale=*(unsigned char*)(tcp_opt->content); tcp_opt=(struct kni_tcp_opt*)((char*)tcp_opt+tcp_opt->len); } else if((tcp_opt->type==0)||(tcp_opt->type==1)) { remain_len-=1; tcp_opt=(struct kni_tcp_opt*)((char*)tcp_opt+1); } else { remain_len-=tcp_opt->len; tcp_opt=(struct kni_tcp_opt*)((char*)tcp_opt+tcp_opt->len); } } return 0; } long kni_state_htable_cb_v4(void* data,const unsigned char* key,unsigned int size,void* user_arg) { long state_flag=STAT_FLAG_NONE; int iprevers; int sni_len=0; char sni[KNI_MAX_BUFLEN]={0}; struct ipaddr addr_ipbmd; struct datainfo_to_tun* datainfo=(struct datainfo_to_tun*)data; struct args_to_tun* arg=(struct args_to_tun*)user_arg; struct ip* iphdr=(struct ip*)(arg->a_packet); struct kni_tcp_hdr* tcphdr=(struct kni_tcp_hdr*)((char*)iphdr+4*(iphdr->ip_hl)); struct layer_addr_mac* mac_addr=(struct layer_addr_mac*)((char*)iphdr-KNI_ETHER_LEN); // if((datainfo==NULL)&&(tcphdr->th_flags&TH_SYN)&&!(tcphdr->th_flags&TH_ACK)) if(datainfo==NULL) { datainfo=(struct datainfo_to_tun*)malloc(sizeof(struct datainfo_to_tun)); memset(datainfo,0,sizeof(struct datainfo_to_tun)); datainfo->route_dir=arg->routdir; /* datainfo->mss[0]=KNI_DEFAULT_MSS; datainfo->mss[1]=KNI_DEFAULT_MSS; datainfo->wnscal[0]=KNI_DEFAULT_WINSCLE; datainfo->wnscal[1]=KNI_DEFAULT_WINSCLE; */ memset(&addr_ipbmd,0,sizeof(struct ipaddr)); addr_ipbmd.addrtype=ADDR_TYPE_IPV4; addr_ipbmd.v4=(struct stream_tuple4_v4*)key; datainfo->state_flag=kni_judge_ipbmd(&addr_ipbmd,arg->thread_seq); kni_get_mss(tcphdr,ntohs(iphdr->ip_len)-4*(iphdr->ip_hl)-arg->tcpdata_len,&(datainfo->mss[KNI_INDEX_SRC]),(unsigned char*)&(datainfo->wnscal[KNI_INDEX_SRC])); //for sendpkt if(arg->iprevers==0) { memcpy(datainfo->smac,mac_addr->src_mac,MAC_ADDR_LEN); memcpy(datainfo->dmac,mac_addr->dst_mac,MAC_ADDR_LEN); } else { memcpy(datainfo->smac,mac_addr->dst_mac,MAC_ADDR_LEN); memcpy(datainfo->dmac,mac_addr->src_mac,MAC_ADDR_LEN); } //end MESA_htable_add(g_kni_structinfo.htable_to_tun_v4, key,size,(void*)datainfo); } if(datainfo==NULL) { return state_flag; } datainfo->pktnum++; iprevers=arg->iprevers; if(datainfo->pro_reply[iprevers]==0) { datainfo->seq[iprevers]=ntohl(tcphdr->th_seq); datainfo->ack[iprevers]=ntohl(tcphdr->th_ack); datainfo->ipid[iprevers]=ntohs(iphdr->ip_id); datainfo->ttl[iprevers]=iphdr->ip_ttl; datainfo->len[iprevers]=ntohs(iphdr->ip_len)-4*iphdr->ip_hl-4*tcphdr->th_off; if(tcphdr->th_flags&TH_SYN) { datainfo->len[iprevers]=1; } } // if((datainfo->state_flag==STAT_FLAG_NONE)&&(arg->iprevers==1)) if((datainfo->state_flag==STAT_FLAG_NONE)&&(datainfo->pktnum==2)) { datainfo->win=ntohs(tcphdr->th_win); kni_get_mss(tcphdr,ntohs(iphdr->ip_len)-4*(iphdr->ip_hl)-arg->tcpdata_len,&(datainfo->mss[KNI_INDEX_DST]),(unsigned char*)&(datainfo->wnscal[KNI_INDEX_DST])); } /* if((datainfo->state_flag==STAT_FLAG_NONE)&&(tcphdr->th_flags&TH_SYN)&&(tcphdr->th_flags&TH_ACK)) { mss=kni_get_mss(tcphdr,ntohs(iphdr->ip_len)-4*(iphdr->ip_hl)-arg->tcpdata_len); datainfo->mss=(datainfo->mssmss:mss; } */ #ifdef KNI_DEBUG_SWITCH return STAT_FLAG_SSL_NOBMD; #endif //only process full stream pkt,star from syn,double dir; if((datainfo->state_flag==STAT_FLAG_NONE)&&(arg->tcpdata_len>0)) { datainfo->state_flag=kni_judge_ssl(arg->tcpdata,arg->tcpdata_len,sni,&sni_len); if(datainfo->state_flag==STAT_FLAG_SSL_NOBMD) { datainfo->state_flag=kni_judge_sni(sni,sni_len,arg->thread_seq); if(datainfo->state_flag==STAT_FLAG_SSL_NOBMD) { // kni_process_fs(arg->a_packet,datainfo->mss); kni_process_tcprepair(arg->a_packet,datainfo->mss,datainfo->wnscal,datainfo->win); } } } return datainfo->state_flag; } long kni_state_htable_cb_v6(void* data,const unsigned char* key,unsigned int size,void* user_arg) { struct ipaddr addr_ipbmd; // struct stream_tuple4_v6* ipv4_addr=(struct stream_tuple4_v6*)key; struct datainfo_to_tun* datainfo=(struct datainfo_to_tun*)data; struct args_to_tun* arg=(struct args_to_tun*)user_arg; if(datainfo==NULL) { datainfo=(struct datainfo_to_tun*)malloc(sizeof(struct datainfo_to_tun)); memset(datainfo,0,sizeof(struct datainfo_to_tun)); MESA_htable_add(g_kni_structinfo.htable_to_tun_v4, key,size,(void*)datainfo); memset(&addr_ipbmd,0,sizeof(struct ipaddr)); addr_ipbmd.addrtype=ADDR_TYPE_IPV6; addr_ipbmd.v4=(struct stream_tuple4_v4*)key; datainfo->state_flag=kni_judge_ipbmd(&addr_ipbmd,arg->thread_seq); } return datainfo->state_flag; } int kni_recv_msg(int socket) { struct msghdr msg = {0}; struct cmsghdr *cmsg; char buf[CMSG_SPACE(sizeof(int))], dup[256]; memset(buf, 0, sizeof(buf)); struct iovec io = { .iov_base = &dup, .iov_len = sizeof(dup) }; msg.msg_iov = &io; msg.msg_iovlen = 1; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); if (recvmsg (socket, &msg, 0) < 0) { printf("recvmsg() error,errno:%d\n",errno); } // handle_error ("Failed to receive message"); cmsg = CMSG_FIRSTHDR(&msg); return 0; } extern "C" int kni_ip_entry(struct streaminfo* f_stream,unsigned char routedir,int thread_seq,struct ip* a_packet) { char ret=APP_STATE_FAWPKT; //ip/tcp info int iplen=ntohs(a_packet->ip_len); struct tcphdr* tcphdr=(struct tcphdr*)((char*)a_packet+4*(a_packet->ip_hl)); char* tcpdata=(char*)tcphdr+4*tcphdr->doff; int tcplen=iplen-4*a_packet->ip_hl-4*tcphdr->doff; unsigned short sport=ntohs(tcphdr->source); unsigned short dport=ntohs(tcphdr->dest); if((sport!=80)&&(sport!=443)&&(dport!=80)&&(dport!=443)) { return ret; } //htable info long state_flag=0; struct stream_tuple4_v4 ipv4_addr; struct args_to_tun usr_arg; usr_arg.a_packet=(void*)a_packet; usr_arg.tcpdata=tcpdata; usr_arg.tcpdata_len=tcplen; usr_arg.thread_seq=thread_seq; usr_arg.iprevers=kni_get_ipaddr_v4(a_packet,&ipv4_addr); if(usr_arg.iprevers==0) { usr_arg.routdir=routedir; } else { usr_arg.routdir=MESA_dir_reverse(routedir); } MESA_htable_search_cb(g_kni_structinfo.htable_to_tun_v4,(unsigned char*)&ipv4_addr,sizeof(struct stream_tuple4_v4),kni_state_htable_cb_v4,(void*)&usr_arg,&state_flag); if(state_flag==STAT_FLAG_SSL_NOBMD) { tun_write_data(g_kni_comminfo.fd_tun[thread_seq],(char*)a_packet,iplen,&ipv4_addr); ret= APP_STATE_DROPPKT; } kni_debug_info_v4((char*)KNI_MODULE_IPENTRY,state_flag,a_packet); return ret; } char kni_ipv6_entry(struct streaminfo *pstream,unsigned char routedir,int thread_seq,void *a_packet) { // int ret; int ip_reverse=0; struct kni_ipv6_hdr* ipv6_hdr=(struct kni_ipv6_hdr*)a_packet; long state_flag=0; struct args_to_tun usr_arg; struct stream_tuple4_v6 ipv6_addr; if(ipv6_hdr->ip6_nex_hdr!=PROTO_TYPE_TCP) { return APP_STATE_DROPME; } ip_reverse=kni_get_ipaddr_v6(a_packet,&ipv6_addr); memset(&usr_arg,0,sizeof(struct args_to_tun)); usr_arg.a_packet=(struct ip*)a_packet; usr_arg.thread_seq=thread_seq; if(ip_reverse==0) { usr_arg.routdir=routedir; } else { usr_arg.routdir=routedir^0x80; } MESA_htable_search_cb(g_kni_structinfo.htable_to_tun_v6,(unsigned char*)&ipv6_addr,sizeof(struct stream_tuple4_v6),kni_state_htable_cb_v6,&usr_arg,&state_flag); if(state_flag==STAT_FLAG_IPBMD) { return APP_STATE_DROPPKT; } tun_write_data_v6(g_kni_comminfo.fd_tun[thread_seq],(char*)a_packet,ntohl(ipv6_hdr->ip6_payload_len)); return APP_STATE_DROPPKT; } int init_profile_info(int* logger_level,char* logger_filepath,int* maat_json_switch,char* table_info_path,char* inc_cfg_dir,char* full_cfg_dir ) { MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"thread_num",&(g_kni_comminfo.thread_num),1); MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"logger_level",logger_level,RLOG_LV_INFO); MESA_load_profile_int_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"maat_json_switch",maat_json_switch,0); MESA_load_profile_string_def((char*)KNI_CONF_FILENAME,(char*)KNI_CONF_MODE,(char*)"logger_filepath",logger_filepath,KNI_CONF_MAXLEN,"./log/kni.log"); 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*)"full_cfg_dir",full_cfg_dir,KNI_CONF_MAXLEN,KNI_FULLCFG_FILEPATH); return 0; } int init_domain_fd() { int i_fd = 0; struct sockaddr_un addr; char serverpath[32] = "/home/server_unixsocket_file"; 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,action:%s",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 ); if ( connect( i_fd, ( struct sockaddr * )&addr, i_addr_len ) < 0 ) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"init_domain_fd():connect error,errno is %d,action:%s",errno,KNI_ACTION_EXIT); return -1; } return i_fd; } 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; } extern "C" char kni_init() { int i=0; int ret=0; char __tun_symbol[512] = "tun0"; int logger_level; char logger_filepath[KNI_CONF_MAXLEN]={0}; int maat_json_switch=0; char table_info_path[KNI_CONF_MAXLEN]={0}; char full_cfg_dir[KNI_CONF_MAXLEN]={0}; char inc_cfg_dir[KNI_CONF_MAXLEN]={0}; // pthread_t pid_write_tun; pthread_t pid_read_tun; inet_aton((const char *)&LOCAL_IP_ADDR,(struct in_addr*)&g_kni_comminfo.local_ip); //init profile init_profile_info(&logger_level,logger_filepath,&maat_json_switch,table_info_path,inc_cfg_dir,full_cfg_dir); //init runtime 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; } //maat 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_json_switch==1) { Maat_set_feather_opt(g_kni_maatinfo.maat_feather,MAAT_OPT_JSON_FILE_PATH, KNI_MAATJSON_FILEPATH,strlen(KNI_MAATJSON_FILEPATH)); } else { 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)); } 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_ipbmd=Maat_table_register(g_kni_maatinfo.maat_feather,KNI_TABLENAME_IPBMD); g_kni_maatinfo.tableid_snibmd=Maat_table_register(g_kni_maatinfo.maat_feather,KNI_TABLENAME_SNIBMD); if((g_kni_maatinfo.tableid_ipbmd<0)||(g_kni_maatinfo.tableid_snibmd<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_ipbmd,g_kni_maatinfo.tableid_snibmd,KNI_ACTION_EXIT); return -1; } //init htable ret=init_kni_stat_htable(); if(ret<0) { return -1; } //init tun 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(__tun_symbol,g_kni_comminfo.thread_num,g_kni_comminfo.fd_tun); if(ret<0) { return -1; } system("ifconfig tun0 192.168.100.1 up"); system("route add default dev tun0"); system("iptables -t mangle -A PREROUTING -p tcp -i tun0 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 50080"); //init domain g_kni_comminfo.fd_domain=init_domain_fd(); if(g_kni_comminfo.fd_domain<0) { MESA_handle_runtime_log(g_kni_comminfo.logger, RLOG_LV_FATAL,KNI_MODULE_INIT,"init_domain_fd()error,action:%s",KNI_ACTION_EXIT); // return -1; } //test init raw_socket g_kni_comminfo.ipv4_fd=(int*)malloc(g_kni_comminfo.thread_num*sizeof(int)); for(i=0;i