2018-06-19 11:47:26 +08:00
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
2018-07-09 11:03:00 +08:00
# include <sys/time.h>
2018-06-19 11:47:26 +08:00
# include <unistd.h>
# include <sys/un.h>
# include <errno.h>
# include <sys/ioctl.h>
# include <linux/if_tun.h>
# include <stddef.h>
# include <net/if.h>
# include <fcntl.h>
# include <sys/socket.h>
2018-07-09 11:03:00 +08:00
# include <linux/socket.h>
//#include <linux/tcp.h>
2018-06-19 11:47:26 +08:00
# include <sys/types.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netinet/ip.h>
# include <netinet/tcp.h>
# include <pthread.h>
# include <net/ethernet.h>
# include <netpacket/packet.h>
# 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"
2018-06-20 10:45:58 +08:00
int g_kni_version_VERSION_20180620 ;
2018-06-19 11:47:26 +08:00
struct kni_var_comm g_kni_comminfo ;
struct kni_var_struct g_kni_structinfo ;
struct kni_var_maat g_kni_maatinfo ;
2018-07-09 11:03:00 +08:00
int g_kni_fds [ 2 ] ;
2018-06-19 11:47:26 +08:00
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 )
{
2018-07-09 11:03:00 +08:00
// return 0;
struct timeval cur_time ;
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-09 11:03:00 +08:00
unsigned int ack = ntohl ( tcphdr - > ack_seq ) ;
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-09 11:03:00 +08:00
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 ) ;
2018-06-19 11:47:26 +08:00
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 ;
}
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 ) ) ;
2018-07-09 11:03:00 +08:00
// ifr.ifr_flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE;
ifr . ifr_flags = IFF_TUN | IFF_NO_PI ;
2018-06-19 11:47:26 +08:00
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 )
{
2018-07-09 11:03:00 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_READTUN , " tun_read_data error,msg is: %s \n " , strerror ( errno ) ) ;
2018-06-19 11:47:26 +08:00
}
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_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_debug_info_v4 ( ( char * ) KNI_MODULE_WRITETUN , STAT_FLAG_SSL_NOBMD , ( struct ip * ) send_buf ) ;
return succ_sendlen ;
}
/********************************************************************************************************************
name :
function :
return :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 kni_sendpkt_eth ( int thread_seq , int iplen , char * ip , struct stream_tuple4_v4 * ipv4_addr , int iprever_flag , uchar * smac , uchar * dmac )
{
int ret = 0 ;
int buflen = iplen + KNITEST_ETH_LEN ;
unsigned char buf [ 2000 ] = { 0 } ;
2018-06-20 10:45:58 +08:00
char * card_in = ( char * ) " p7p1 " ;
char * card_out = ( char * ) " em2 " ;
2018-06-19 11:47:26 +08:00
unsigned short eth_type = 0x0800 ;
2018-06-20 10:45:58 +08:00
// struct ip* iphdr=(struct ip*)ip;
2018-06-19 11:47:26 +08:00
uchar * tmp_smac ;
uchar * tmp_dmac ;
char * if_name = NULL ;
if ( iprever_flag = = 0 )
{
if_name = card_out ;
tmp_smac = smac ;
tmp_dmac = dmac ;
}
else
{
if_name = card_in ;
tmp_smac = dmac ;
tmp_dmac = smac ;
}
struct ifreq ifr ;
size_t ifname_len = strlen ( if_name ) ;
if ( ifname_len < sizeof ( ifr . ifr_name ) )
{
2018-07-09 11:03:00 +08:00
memset ( ifr . ifr_name , 0 , IFNAMSIZ ) ;
2018-06-19 11:47:26 +08:00
memcpy ( ifr . ifr_name , if_name , ifname_len ) ;
}
else
{
2018-07-09 11:03:00 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_SENDPKT , " interface name is too long \n " ) ;
2018-06-19 11:47:26 +08:00
return - 1 ;
}
if ( - 1 = = ioctl ( g_kni_comminfo . ipv4_fd [ thread_seq ] , SIOCGIFINDEX , & ifr ) )
{
2018-07-09 11:03:00 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_SENDPKT , " get if index error:%d,card:%s " , errno , ifr . ifr_name ) ;
2018-06-19 11:47:26 +08:00
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 ;
}
2018-07-09 11:03:00 +08:00
// unsigned char* mac=(unsigned char*)ifr.ifr_hwaddr.sa_data;
// printf("%02x:%02x:%02x:%02x:%02x:%02x\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
2018-06-19 11:47:26 +08:00
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 ) ) ;
}
else
{
kni_debug_info_v4 ( ( char * ) KNI_MODULE_SENDPKT , STAT_FLAG_SSL_NOBMD , ( struct ip * ) ip ) ;
}
return ret ;
}
2018-07-09 11:03:00 +08:00
int kni_keepalive_replay ( struct stream_tuple4_v4 * ipv4_addr , int iprever_flag , struct datainfo_to_tun * datainfo , void * a_packet , int iplen , int thread_seq )
{
int index = 1 - iprever_flag ;
unsigned short win = datainfo - > win ;
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 ;
}
2018-06-19 11:47:26 +08:00
long kni_readtun_htable_cb_v4 ( void * data , const unsigned char * key , unsigned int size , void * user_arg )
{
long result = 0 ;
2018-07-09 11:03:00 +08:00
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;
2018-06-19 11:47:26 +08:00
struct datainfo_to_tun * datainfo = ( struct datainfo_to_tun * ) data ;
if ( datainfo ! = NULL )
{
2018-07-09 11:03:00 +08:00
// 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 ;
}
2018-06-19 11:47:26 +08:00
}
2018-07-09 11:03:00 +08:00
/*
# 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
*/
2018-06-19 11:47:26 +08:00
return result ;
}
int kni_process_readdata ( int thread_seq , int buflen , char * buf )
{
2018-07-09 11:03:00 +08:00
int ret ;
2018-06-19 11:47:26 +08:00
int iprever_flag = 0 ;
long result = 0 ;
2018-07-09 11:03:00 +08:00
// struct datainfo_to_tun datainfo;
struct args_read_tun args ;
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-09 11:03:00 +08:00
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 ) ;
2018-06-19 11:47:26 +08:00
if ( result = = 1 )
{
2018-07-09 11:03:00 +08:00
kni_sendpkt_eth ( thread_seq , buflen , buf , & ipv4_addr , iprever_flag , args . smac , args . dmac ) ;
2018-06-19 11:47:26 +08:00
}
}
else
{
iprever_flag = kni_get_ipaddr_v6 ( ( void * ) buf , & ipv6_addr ) ;
}
2018-07-09 11:03:00 +08:00
2018-06-19 11:47:26 +08:00
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 ; i < g_kni_comminfo . thread_num ; i + + )
{
recv_len = 0 ;
memset ( recv_buf , 0 , KNI_MAX_BUFLEN ) ;
recv_len = tun_read_data ( g_kni_comminfo . fd_tun [ i ] , 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
{
kni_process_readdata ( 0 , recv_len , recv_buf ) ;
}
}
}
return 0 ;
}
/********************************************************************************************************************
name :
function :
return :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct tcp_state * fs_get_default_state ( )
{
struct tcp_state * st ;
st = ( struct tcp_state * ) malloc ( sizeof ( struct tcp_state ) ) ;
if ( st = = NULL ) {
return NULL ;
}
memset ( st , 0 , sizeof ( struct tcp_state ) ) ;
st - > tstamp_ok = 0 ;
st - > sack_ok = 0 ;
st - > wscale_ok = 0 ;
st - > ecn_ok = 0 ;
2018-07-09 11:03:00 +08:00
// st->snd_wscale = 0;
// st->rcv_wscale = 0;
st - > snd_wscale = 128 ;
st - > rcv_wscale = 128 ;
2018-06-19 11:47:26 +08:00
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 } ;
2018-06-20 10:45:58 +08:00
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 )
2018-06-19 11:47:26 +08:00
{
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 ) ;
2018-06-20 10:45:58 +08:00
fs_set_state ( fds [ KNI_FDS_INDEX_CLIENT ] , fake_server ) ;
fs_set_state ( fds [ KNI_FDS_INDEX_SERVER ] , fake_client ) ;
2018-06-19 11:47:26 +08:00
kni_send_fds ( g_kni_comminfo . fd_domain , fds , 2 ) ;
2018-07-09 11:03:00 +08:00
// kni_debug_info_v4((char*)KNI_MODULE_SENDFD,STAT_FLAG_SSL_NOBMD,(struct ip*)a_packet);
2018-06-20 10:45:58 +08:00
close ( fds [ KNI_FDS_INDEX_CLIENT ] ) ;
close ( fds [ KNI_FDS_INDEX_SERVER ] ) ;
2018-06-19 11:47:26 +08:00
return 0 ;
}
2018-07-09 11:03:00 +08:00
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 ) < < wnscale [ KNI_INDEX_SRC ] ;
fserver_win . max_window = fserver_win . snd_wnd ;
fserver_win . rcv_wnd = win ;
fserver_win . rcv_wup = ntohl ( tcphdr - > 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 ) < < wnscale [ KNI_INDEX_SRC ] ;
fclient_win . rcv_wup = ntohl ( tcphdr - > ack_seq ) ;
/*
//c has get
fclient_win . snd_wl1 = ntohl ( tcphdr - > ack_seq ) ;
fclient_win . snd_wnd = ntohs ( tcphdr - > window ) < < wnscale [ KNI_INDEX_SRC ] ;
fclient_win . max_window = fclient_win . snd_wnd ;
fclient_win . rcv_wnd = fclient_win . snd_wnd ;
fclient_win . rcv_wup = fclient_win . snd_wl1 ;
*/
tcprepair_set_state ( fd_client , & fake_server , fserver_win ) ;
tcprepair_set_state ( fd_server , & fake_client , fclient_win ) ;
fds [ 0 ] = fd_client ;
fds [ 1 ] = fd_server ;
kni_send_fds ( g_kni_comminfo . fd_domain , fds , 2 ) ;
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " mss_src:%d,mss_dst:%d,wnscale_src:%d,wnscale_dst:%d " , mss [ 0 ] , mss [ 1 ] , wnscale [ 0 ] , wnscale [ 1 ] ) ;
return 0 ;
}
2018-06-19 11:47:26 +08:00
/***************************************************************************************
return : state_flag
kni_bmd : STAT_FLAG_SNIBMD
not kni_bmd : STAT_FLAG_SSL_NOBMD
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int kni_judge_sni ( char * sni , int sni_len , int thread_seq )
{
int state_flag = STAT_FLAG_SSL_NOBMD ;
int string_scan_num = 0 ;
int found_pos ;
scan_status_t mid = NULL ;
struct Maat_rule_t maat_result [ KNI_MAX_CFGNUM ] ;
string_scan_num = Maat_full_scan_string ( g_kni_maatinfo . maat_feather , g_kni_maatinfo . tableid_snibmd , CHARSET_GBK , sni , sni_len , maat_result , & found_pos , KNI_MAX_CFGNUM , & mid , thread_seq ) ;
Maat_clean_status ( & mid ) ;
if ( string_scan_num > 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_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 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 ;
}
2018-07-09 11:03:00 +08:00
int kni_get_mss ( struct kni_tcp_hdr * tcphdr , int tcp_hdr_len , unsigned short * mss , unsigned char * winscale )
2018-06-19 11:47:26 +08:00
{
2018-07-09 11:03:00 +08:00
// unsigned short mss=KNI_DEFAULT_MSS;
* mss = KNI_DEFAULT_MSS ;
* winscale = KNI_DEFAULT_WINSCLE ;
2018-06-19 11:47:26 +08:00
2018-07-09 11:03:00 +08:00
// return 0;
2018-06-19 11:47:26 +08:00
int remain_len = tcp_hdr_len ;
struct kni_tcp_opt * tcp_opt = NULL ;
if ( ( tcp_hdr_len < = 20 ) | | ( tcp_hdr_len > 64 ) )
{
2018-07-09 11:03:00 +08:00
return 0 ;
2018-06-19 11:47:26 +08:00
}
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
{
2018-07-09 11:03:00 +08:00
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 ) ;
2018-06-19 11:47:26 +08:00
}
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 ) ;
}
}
2018-07-09 11:03:00 +08:00
return 0 ;
2018-06-19 11:47:26 +08:00
}
long kni_state_htable_cb_v4 ( void * data , const unsigned char * key , unsigned int size , void * user_arg )
{
long state_flag = STAT_FLAG_NONE ;
2018-07-09 11:03:00 +08:00
int iprevers ;
2018-06-19 11:47:26 +08:00
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 ) ) ;
2018-07-09 11:03:00 +08:00
memset ( datainfo , 0 , sizeof ( struct datainfo_to_tun ) ) ;
2018-06-19 11:47:26 +08:00
datainfo - > route_dir = arg - > routdir ;
2018-07-09 11:03:00 +08:00
/*
datainfo - > mss [ 0 ] = KNI_DEFAULT_MSS ;
datainfo - > mss [ 1 ] = KNI_DEFAULT_MSS ;
datainfo - > wnscal [ 0 ] = KNI_DEFAULT_WINSCLE ;
datainfo - > wnscal [ 1 ] = KNI_DEFAULT_WINSCLE ;
*/
2018-06-19 11:47:26 +08:00
memset ( & addr_ipbmd , 0 , sizeof ( struct ipaddr ) ) ;
addr_ipbmd . addrtype = ADDR_TYPE_IPV4 ;
addr_ipbmd . v4 = ( struct stream_tuple4_v4 * ) key ;
2018-07-09 11:03:00 +08:00
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
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-09 11:03:00 +08:00
2018-06-19 11:47:26 +08:00
}
if ( datainfo = = NULL )
{
return state_flag ;
}
2018-07-09 11:03:00 +08:00
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 ] ) ) ;
}
/*
2018-06-19 11:47:26 +08:00
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 - > mss < mss ) ? datainfo - > mss : mss ;
}
*/
2018-07-09 11:03:00 +08:00
# ifdef KNI_DEBUG_SWITCH
return STAT_FLAG_SSL_NOBMD ;
# endif
2018-06-19 11:47:26 +08:00
//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 )
{
2018-07-09 11:03:00 +08:00
// kni_process_fs(arg->a_packet,datainfo->mss);
kni_process_tcprepair ( arg - > a_packet , datainfo - > mss , datainfo - > wnscal , datainfo - > win ) ;
2018-06-19 11:47:26 +08:00
}
}
}
2018-07-09 11:03:00 +08:00
return datainfo - > state_flag ;
2018-06-19 11:47:26 +08:00
}
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 ;
}
2018-07-09 11:03:00 +08:00
int kni_recv_msg ( int socket )
2018-06-19 11:47:26 +08:00
{
2018-07-09 11:03:00 +08:00
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 ) ;
2018-06-19 11:47:26 +08:00
2018-07-09 11:03:00 +08:00
return 0 ;
}
extern " C " int kni_ip_entry ( struct streaminfo * f_stream , unsigned char routedir , int thread_seq , struct ip * a_packet )
{
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-09 11:03:00 +08:00
if ( ( i_fd = socket ( AF_UNIX , SOCK_STREAM , 0 ) ) < 0 )
// if ( ( i_fd = socket( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 )
2018-06-19 11:47:26 +08:00
{
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 ) ) ;
2018-07-09 11:03:00 +08:00
memset ( g_kni_comminfo . fd_tun , 0 , g_kni_comminfo . thread_num * sizeof ( int ) ) ;
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-09 11:03:00 +08:00
// return -1;
2018-06-19 11:47:26 +08:00
}
//test init raw_socket
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 ;
}
}
pthread_create ( & pid_read_tun , NULL , kni_read_tun , NULL ) ;
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " KNI_INIT succ! " ) ;
return 0 ;
}