2018-06-19 11:47:26 +08:00
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
2018-07-11 18:59:23 +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-11 18:59:23 +08:00
# include <linux/socket.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"
2018-07-11 18:59:23 +08:00
# include "field_stat2.h"
2018-06-19 11:47:26 +08:00
# include "kni.h"
2018-07-10 09:32:18 +08:00
2018-07-18 10:37:20 +08:00
int g_kni_version_VERSION_20180718 ;
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-11 18:59:23 +08:00
struct kni_fs2_info g_kni_fs2_info ;
2018-07-12 17:49:00 +08:00
struct kni_switch_info g_kni_switch_info ;
2018-06-19 11:47:26 +08:00
2018-07-18 10:37:20 +08:00
char g_kni_cardname [ KNI_CARD_NUM ] [ KNI_CONF_MAXLEN ] ;
2018-07-11 18:59:23 +08:00
int g_kni_threadseq [ KNI_MAX_THREADNUM ] ;
const char * g_kni_fs2_name [ FS2_COLUMN_NUM ] = { " RECV_PKTS " , " FWD_PKTS " , " DROP_PKTS " , " WRITE_PKTS " , " READ_PKTS " , " SEND_PKTS " } ;
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 )
{
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 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-10 09:32:18 +08:00
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 " , saddr_v4 , sport , daddr_v4 , dport , state_flag , iplen , seq ) ;
2018-06-19 11:47:26 +08:00
return 0 ;
}
2018-07-11 18:59:23 +08:00
/*
int kni_filestate2_init ( )
{
int i = 0 ;
int j = 0 ;
int value = 1 ;
unsigned int fs2_sport ;
char fs2_filename [ KNI_MAX_BUFLEN ] = { 0 } ;
char fs2_sip [ KNI_MAX_BUFLEN ] = { 0 } ;
MESA_load_profile_string_def ( ( char * ) KNI_CONF_FILENAME , ( char * ) KNI_CONF_MODE , ( char * ) " filestat2_filename " , fs2_filename , KNI_MAX_BUFLEN , ( char * ) " ./log/kni_fs2.log " ) ;
MESA_load_profile_string_def ( ( char * ) KNI_CONF_FILENAME , ( char * ) KNI_CONF_MODE , ( char * ) " filestat2_sip " , fs2_sip , KNI_MAX_BUFLEN , ( char * ) " 10.127.208.15 " ) ;
MESA_load_profile_uint_def ( ( char * ) KNI_CONF_FILENAME , ( char * ) KNI_CONF_MODE , ( char * ) " filestat2_sport " , ( unsigned int * ) & fs2_sport , 8125 ) ;
g_kni_fs2_info . handler = FS_create_handle ( ) ;
FS_set_para ( g_kni_comminfo . fs2_handler , OUTPUT_DEVICE , fs2_filename , strlen ( fs2_filename ) + 1 ) ;
FS_set_para ( g_kni_comminfo . fs2_handler , PRINT_MODE , & value , sizeof ( value ) ) ;
FS_set_para ( g_kni_comminfo . fs2_handler , STAT_CYCLE , & value , sizeof ( value ) ) ;
FS_set_para ( g_kni_comminfo . fs2_handler , CREATE_THREAD , & value , sizeof ( value ) ) ;
FS_set_para ( g_kni_comminfo . fs2_handler , APP_NAME , STEWARD_FS2_APPNAME , strlen ( STEWARD_FS2_APPNAME ) + 1 ) ;
FS_set_para ( g_kni_comminfo . fs2_handler , STATS_SERVER_IP , fs2_sip , strlen ( fs2_sip ) + 1 ) ;
FS_set_para ( g_kni_comminfo . fs2_handler , STATS_SERVER_PORT , & fs2_sport , sizeof ( int ) ) ;
for ( i = 0 ; i < FS2_COLUMN_NUM ; i + + )
{
g_kni_fs2_info . column_id [ i ] = FS_register ( g_kni_fs2_info . handler , FS_STYLE_FIELD , FS_CALC_CURRENT , g_kni_fs2_name [ i ] ) ;
}
FS_start ( g_kni_fs2_info . handler ) ;
return 0 ;
}
void * kni_filestat2 ( void * arg )
{
int i = 0 ;
int j = 0 ;
unsigned long long column_value [ STEWARD_COLUMN_NUM ] ;
kni_filestate2_init ( ) ;
while ( 1 )
{
for ( i = 0 ; i < STEWARD_COLUMN_NUM ; i + + )
{
column_value [ i ] = 0 ;
for ( j = 0 ; j < g_iThreadNum ; j + + )
{
column_value [ i ] + = g_kni_fs2_info . column_value [ j ] [ i ] ;
}
FS_operate ( g_kni_fs2_info . handler , g_kni_fs2_info . column_id [ i ] , 0 , FS_OP_SET , column_value [ i ] ) ;
}
sleep ( 1 ) ;
}
return NULL ;
}
*/
2018-06-19 11:47:26 +08:00
/****************************************************************************
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 ;
}
2018-07-10 09:32:18 +08:00
static int kni_send_fds ( int socket , int * fds , int n , int protocol )
2018-06-19 11:47:26 +08:00
{
2018-07-10 09:32:18 +08:00
int flags = MSG_NOSIGNAL ;
2018-06-19 11:47:26 +08:00
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 ) } ;
2018-07-10 09:32:18 +08:00
//tlv info
struct kni_tlv_info tlv_info ;
tlv_info . type = KNI_TLV_TYPE_PRO ;
tlv_info . len = 0x0001 ;
tlv_info . value = protocol ;
memcpy ( dup , & tlv_info , sizeof ( struct kni_tlv_info ) ) ;
//end
2018-06-19 11:47:26 +08:00
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 ) ) ;
2018-07-10 09:32:18 +08:00
// if (sendmsg (socket, &msg, 0) < 0)
if ( sendmsg ( socket , & msg , flags ) < 0 )
2018-06-19 11:47:26 +08:00
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " kni_send_fds " , " sendmsg()error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-10 09:32:18 +08:00
return - 1 ;
2018-06-19 11:47:26 +08:00
}
2018-07-10 09:32:18 +08:00
return 0 ;
2018-06-19 11:47:26 +08:00
}
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 ;
2018-07-10 09:32:18 +08:00
int flag = 0 ;
2018-06-19 11:47:26 +08:00
struct ifreq ifr ;
2018-07-10 09:32:18 +08:00
2018-06-19 11:47:26 +08:00
char * clonedev = ( char * ) " /dev/net/tun " ;
memset ( & ifr , 0 , sizeof ( ifr ) ) ;
2018-07-10 09:32:18 +08:00
ifr . ifr_flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE ;
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 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " tun_alloc_mq():open error,errno is:%d,%s,action:%s " , errno , strerror ( errno ) , KNI_ACTION_EXIT ) ;
2018-06-19 11:47:26 +08:00
tun_error ( i , fds ) ;
return - 1 ;
}
err = ioctl ( fd , TUNSETIFF , ( void * ) & ifr ) ;
if ( err )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " tun_alloc_mq():ioctl error,errno is:%d,%s,action:%s " , errno , strerror ( errno ) , KNI_ACTION_EXIT ) ;
2018-06-19 11:47:26 +08:00
close ( fd ) ;
tun_error ( i , fds ) ;
return - 1 ;
}
2018-07-10 09:32:18 +08:00
//20180618 add set noblock
flag = fcntl ( fd , F_GETFL , 0 ) ;
if ( flag < 0 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " fcntl():getfl error,errno is:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-10 09:32:18 +08:00
}
if ( fcntl ( fd , F_SETFL , flag | O_NONBLOCK ) < 0 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " fcntl():setfl error,errno is:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-10 09:32:18 +08:00
}
//end
2018-06-19 11:47:26 +08:00
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 ;
2018-07-10 09:32:18 +08:00
while ( 1 )
2018-06-19 11:47:26 +08:00
{
2018-07-10 09:32:18 +08:00
recv_len = read ( fd , recv_buf , KNI_MAX_BUFLEN ) ;
if ( ( recv_len < 0 ) & & ( errno = = 11 ) )
{
continue ;
}
else if ( recv_len < 0 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_WRITETUN , " tun_read_data error %d, %s \n " , errno , strerror ( errno ) ) ;
2018-07-10 09:32:18 +08:00
return - 1 ;
}
else
{
return recv_len ;
}
2018-06-19 11:47:26 +08:00
}
2018-07-10 09:32:18 +08:00
return 0 ;
2018-06-19 11:47:26 +08:00
}
/********************************************************************************************************************
name :
function :
return :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-07-11 18:59:23 +08:00
char tun_write_data ( int fd , char * send_buf , int send_buflen , struct streaminfo * pstream )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME ;
2018-06-19 11:47:26 +08:00
int succ_sendlen = 0 ;
succ_sendlen = write ( fd , send_buf , send_buflen ) ;
2018-07-11 18:59:23 +08:00
if ( ( succ_sendlen < 0 ) & & ( pstream ! = NULL ) )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
MESA_kill_tcp ( pstream , ( const void * ) send_buf ) ;
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_WRITETUN , " write() error %d, %s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
ret = APP_STATE_DROPPKT | APP_STATE_DROPME ;
2018-06-19 11:47:26 +08:00
}
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 ) ;
}
2018-07-11 18:59:23 +08:00
kni_debug_info_v4 ( ( char * ) KNI_MODULE_WRITETUN , KNI_FLAG_SSL , ( struct ip * ) send_buf ) ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
return ret ;
2018-06-19 11:47:26 +08:00
}
/********************************************************************************************************************
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 ;
}
2018-07-18 10:37:20 +08:00
int kni_sendpkt_routdir ( int thread_seq , int iplen , char * ip , struct stream_tuple4_v4 * ipv4_addr , int iprever_flag , int routdir , uchar * smac , uchar * dmac )
{
int ret = 0 ;
int buflen = iplen + KNI_ETHER_LEN ;
unsigned char buf [ 2000 ] = { 0 } ;
unsigned short eth_type = 0x0800 ;
uchar * tmp_smac ;
uchar * tmp_dmac ;
char * if_name = NULL ;
if ( iprever_flag = = 0 )
{
tmp_smac = smac ;
tmp_dmac = dmac ;
}
else
{
tmp_smac = dmac ;
tmp_dmac = smac ;
}
if_name = g_kni_cardname [ 1 - routdir ] ;
struct ifreq ifr ;
size_t ifname_len = strlen ( if_name ) ;
if ( ifname_len < sizeof ( ifr . ifr_name ) )
{
memset ( ifr . ifr_name , 0 , IFNAMSIZ ) ;
memcpy ( ifr . ifr_name , if_name , ifname_len ) ;
}
else
{
printf ( " interface name is too long \n " ) ;
return - 1 ;
}
if ( - 1 = = ioctl ( g_kni_comminfo . ipv4_fd [ thread_seq ] , SIOCGIFINDEX , & ifr ) )
{
printf ( " get if index error:%d,%s " , errno , strerror ( errno ) ) ;
return - 1 ;
}
struct sockaddr_ll addr = { 0 } ;
addr . sll_family = AF_PACKET ;
addr . sll_halen = ETHER_ADDR_LEN ;
addr . sll_ifindex = ifr . ifr_ifindex ;
addr . sll_protocol = htons ( ETH_P_IP ) ;
memcpy ( addr . sll_addr , tmp_dmac , ETHER_ADDR_LEN ) ;
if ( ioctl ( g_kni_comminfo . ipv4_fd [ thread_seq ] , SIOCGIFHWADDR , & ifr ) = = - 1 )
{
return - 1 ;
}
sendpacket_build_ethernet ( ( unsigned char * ) tmp_dmac , ( unsigned char * ) tmp_smac , eth_type , ( const unsigned char * ) ip , iplen , ( unsigned char * ) buf ) ;
ret = sendto ( g_kni_comminfo . ipv4_fd [ thread_seq ] , buf , buflen , 0 , ( struct sockaddr * ) & addr , sizeof ( addr ) ) ;
if ( ret < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_SENDPKT , " sendto() error,errno:%d,msg:%s! " , errno , strerror ( errno ) ) ;
}
else
{
kni_debug_info_v4 ( ( char * ) KNI_MODULE_SENDPKT , KNI_FLAG_SSL , ( struct ip * ) ip ) ;
}
return ret ;
}
int kni_sendpkt_eth ( int thread_seq , int iplen , char * ip , struct stream_tuple4_v4 * ipv4_addr , int iprever_flag , int routdir , uchar * smac , uchar * dmac )
2018-06-19 11:47:26 +08:00
{
int ret = 0 ;
2018-07-11 18:59:23 +08:00
int buflen = iplen + KNI_ETHER_LEN ;
2018-06-19 11:47:26 +08:00
unsigned char buf [ 2000 ] = { 0 } ;
2018-07-17 10:18:08 +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 )
{
2018-07-17 10:18:08 +08:00
// if_name=card_out;
if_name = g_kni_comminfo . card_out ;
2018-06-19 11:47:26 +08:00
tmp_smac = smac ;
tmp_dmac = dmac ;
}
else
{
2018-07-17 10:18:08 +08:00
// if_name=card_in;
if_name = g_kni_comminfo . card_in ;
2018-06-19 11:47:26 +08:00
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-11 18:59:23 +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-10 09:32:18 +08:00
printf ( " 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-18 10:37:20 +08:00
printf ( " get if index error:%d,%s " , errno , strerror ( errno ) ) ;
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-11 18:59:23 +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
{
2018-07-11 18:59:23 +08:00
kni_debug_info_v4 ( ( char * ) KNI_MODULE_SENDPKT , KNI_FLAG_SSL , ( struct ip * ) ip ) ;
2018-06-19 11:47:26 +08:00
}
return ret ;
}
2018-07-11 18:59:23 +08:00
int kni_keepalive_replay ( struct stream_tuple4_v4 * ipv4_addr , int iprever_flag , struct kni_htable_datainfo * datainfo , void * a_packet , int iplen , int thread_seq )
{
# ifdef KNI_DEBUG_TCPREPAIR
return 0 ;
# endif
# ifdef KNI_DEBUG_KEEPALIVE
return 0 ;
# endif
2018-07-16 15:23:21 +08:00
2018-07-11 18:59:23 +08:00
int index = 1 - iprever_flag ;
// unsigned short ipid=random()%65535;
struct ip * iphdr = ( struct ip * ) a_packet ;
struct tcphdr * tcphdr = ( struct tcphdr * ) ( ( char * ) iphdr + 4 * ( iphdr - > ip_hl ) ) ;
struct kni_wndpro_reply_info * tcpinfo = & ( datainfo - > lastpkt_info [ index ] ) ;
struct ip * snd_iphdr = NULL ;
struct tcphdr * snd_tcphdr = NULL ;
char * sendbuf = ( char * ) malloc ( iplen ) ;
memcpy ( sendbuf , a_packet , iplen ) ;
snd_iphdr = ( struct ip * ) sendbuf ;
snd_tcphdr = ( struct tcphdr * ) ( ( char * ) snd_iphdr + 4 * ( snd_iphdr - > ip_hl ) ) ;
( snd_iphdr - > ip_src ) . s_addr = ( iphdr - > ip_dst ) . s_addr ;
( snd_iphdr - > ip_dst ) . s_addr = ( iphdr - > ip_src ) . s_addr ;
// snd_iphdr->ip_id=ipid;
// snd_iphdr->ip_id=htons(datainfo->lastpkt_info[index].ipid+1);
// snd_iphdr->ip_ttl=datainfo->lastpkt_info[index].ttl;
snd_tcphdr - > source = tcphdr - > dest ;
snd_tcphdr - > dest = tcphdr - > source ;
snd_tcphdr - > seq = htonl ( tcpinfo - > seq + tcpinfo - > len ) ;
snd_tcphdr - > ack_seq = htonl ( tcpinfo - > ack ) ;
if ( tcpinfo - > syn_flag = = 1 )
{
snd_tcphdr - > seq = htonl ( ntohl ( snd_tcphdr - > seq ) + 1 ) ;
}
/*
if ( iprever_flag = = 0 )
{
snd_iphdr - > ip_id = ipid ;
snd_tcphdr - > window = htons ( ( win > > win_scale ) + 1 ) ;
}
*/
sendpacket_do_checksum ( ( unsigned char * ) sendbuf , IPPROTO_TCP , ( iplen - 4 * ( iphdr - > ip_hl ) ) ) ;
sendpacket_do_checksum ( ( unsigned char * ) sendbuf , IPPROTO_IP , sizeof ( struct ip ) ) ;
tun_write_data ( g_kni_comminfo . fd_tun [ thread_seq ] , sendbuf , iplen , NULL ) ;
kni_debug_info_v4 ( ( char * ) " recv_keepalive_request " , 5 , ( struct ip * ) a_packet ) ;
kni_debug_info_v4 ( ( char * ) " send_keepalive_replay " , 5 , ( struct ip * ) sendbuf ) ;
free ( sendbuf ) ;
sendbuf = NULL ;
datainfo - > wndpro_flag [ index ] = 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-11 18:59:23 +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 kni_htable_datainfo * datainfo = ( struct kni_htable_datainfo * ) data ;
2018-06-19 11:47:26 +08:00
if ( datainfo ! = NULL )
{
2018-07-11 18:59:23 +08:00
memcpy ( args - > smac , datainfo - > smac , KNI_MACADDR_LEN ) ;
memcpy ( args - > dmac , datainfo - > dmac , KNI_MACADDR_LEN ) ;
2018-07-18 10:37:20 +08:00
if ( args - > iprevers = = 0 )
{
args - > routdir = datainfo - > route_dir ;
}
else
{
// args->routdir=MESA_dir_reverse(datainfo->route_dir);
args - > routdir = 1 - datainfo - > route_dir ;
}
2018-07-11 18:59:23 +08:00
if ( datainfo - > wndpro_flag [ 1 - args - > iprevers ] > 0 )
{
result = 1 ;
}
else
{
kni_keepalive_replay ( ipv4_addr , args - > iprevers , datainfo , args - > a_packet , args - > iplen , args - > thread_seq ) ;
result = 1 ;
}
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
}
# ifdef KNI_DEBUG_TCPREPAIR
else if ( ipv4_addr - > saddr = = 1698867392 )
{
printf ( " sip is 192.168.66.101 \n " ) ;
args - > smac [ 0 ] = 0x18 ;
args - > smac [ 1 ] = 0x66 ;
args - > smac [ 2 ] = 0xda ;
args - > smac [ 3 ] = 0xe5 ;
args - > smac [ 4 ] = 0xfa ;
args - > smac [ 5 ] = 0xa1 ;
args - > dmac [ 0 ] = 0xe8 ;
args - > dmac [ 1 ] = 0x61 ;
args - > dmac [ 2 ] = 0x1f ;
args - > dmac [ 3 ] = 0x13 ;
args - > dmac [ 4 ] = 0x70 ;
args - > dmac [ 5 ] = 0x7a ;
2018-07-10 16:04:54 +08:00
result = 1 ;
}
2018-07-11 18:59:23 +08:00
else
{
kni_debug_info_v4 ( ( char * ) " read_tun,data=NULL,sip not 192.168.66.101 " , 0 , ( struct ip * ) args - > a_packet ) ;
}
# endif
2018-06-19 11:47:26 +08:00
return result ;
}
2018-07-11 18:59:23 +08:00
2018-07-10 09:32:18 +08:00
int init_domain_fd ( )
{
int i_fd = 0 ;
struct sockaddr_un addr ;
2018-07-17 10:18:08 +08:00
// char serverpath[32] = "/home/server_unixsocket_file";
2018-07-10 09:32:18 +08:00
int i_addr_len = sizeof ( struct sockaddr_un ) ;
2018-07-11 18:59:23 +08:00
if ( ( i_fd = socket ( AF_UNIX , SOCK_STREAM , 0 ) ) < 0 )
// if ( ( i_fd = socket( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 )
2018-07-10 09:32:18 +08:00
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " init_domain_fd():socket error,errno is %d,%s,,action:%s " , errno , strerror ( errno ) , KNI_ACTION_EXIT ) ;
2018-07-10 09:32:18 +08:00
return - 1 ;
}
//fill socket adress structure with server's address
memset ( & addr , 0 , sizeof ( addr ) ) ;
addr . sun_family = AF_UNIX ;
2018-07-17 10:18:08 +08:00
// strncpy( addr.sun_path, serverpath, sizeof( addr.sun_path ) - 1 );
strncpy ( addr . sun_path , g_kni_comminfo . domain_path , sizeof ( addr . sun_path ) - 1 ) ;
2018-07-10 09:32:18 +08:00
if ( connect ( i_fd , ( struct sockaddr * ) & addr , i_addr_len ) < 0 )
{
2018-07-17 10:29:37 +08:00
close ( i_fd ) ;
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " init_domain_fd():connect error,errno is %d,%s,action:%s " , errno , strerror ( errno ) , KNI_ACTION_EXIT ) ;
2018-07-10 09:32:18 +08:00
return - 1 ;
}
2018-07-17 10:34:26 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " init_domain_fd():domain socket connect succ! " ) ;
2018-07-10 09:32:18 +08:00
return i_fd ;
}
2018-06-19 11:47:26 +08:00
int kni_process_readdata ( int thread_seq , int buflen , char * buf )
{
int iprever_flag = 0 ;
long result = 0 ;
struct ip * iphdr = ( struct ip * ) buf ;
struct stream_tuple4_v4 ipv4_addr ;
2018-07-11 18:59:23 +08:00
struct args_read_tun args ;
2018-06-19 11:47:26 +08:00
if ( iphdr - > ip_v = = 4 )
{
iprever_flag = kni_get_ipaddr_v4 ( ( void * ) buf , & ipv4_addr ) ;
2018-07-11 18:59:23 +08:00
kni_debug_info_v4 ( ( char * ) KNI_MODULE_READTUN , KNI_FLAG_SSL , ( struct ip * ) buf ) ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +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-10 09:32:18 +08:00
2018-07-18 10:37:20 +08:00
// kni_sendpkt_eth(thread_seq,buflen,buf,&ipv4_addr,iprever_flag,args.routdir,args.smac,args.dmac);
kni_sendpkt_routdir ( thread_seq , buflen , buf , & ipv4_addr , iprever_flag , args . routdir , args . smac , args . dmac ) ;
2018-06-19 11:47:26 +08:00
}
}
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 )
{
2018-07-11 18:59:23 +08:00
int thread_seq = * ( int * ) arg ;
2018-06-19 11:47:26 +08:00
int recv_len = 0 ;
char recv_buf [ KNI_MAX_BUFLEN ] = { 0 } ;
while ( 1 )
{
2018-07-10 09:32:18 +08:00
if ( g_kni_comminfo . kni_mode_cur = = KNI_MODE_BYPASS )
2018-06-19 11:47:26 +08:00
{
2018-07-10 09:32:18 +08:00
sleep ( KNI_USLEEP_TIME ) ;
continue ;
}
2018-07-11 18:59:23 +08:00
recv_len = 0 ;
memset ( recv_buf , 0 , KNI_MAX_BUFLEN ) ;
recv_len = tun_read_data ( g_kni_comminfo . fd_tun [ thread_seq ] , recv_buf , KNI_MAX_BUFLEN ) ;
if ( recv_len < 0 )
2018-07-10 09:32:18 +08:00
{
2018-07-11 18:59:23 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_READTUN , " tun_read_data()error,recv_len:%d " , recv_len ) ;
}
else if ( recv_len > 0 )
{
kni_process_readdata ( thread_seq , recv_len , recv_buf ) ;
2018-06-19 11:47:26 +08:00
}
}
return 0 ;
}
2018-07-10 09:32:18 +08:00
int kni_sendfds_domain ( )
2018-06-19 11:47:26 +08:00
{
2018-07-10 09:32:18 +08:00
int ret = 0 ;
2018-07-11 18:59:23 +08:00
long fds_len = KNI_FDS_NUM * sizeof ( int ) ;
2018-07-10 09:32:18 +08:00
int fds [ KNI_FDS_NUM ] = { 0 } ;
while ( 1 )
{
memset ( fds , 0 , KNI_FDS_NUM * sizeof ( int ) ) ;
fds_len = KNI_FDS_NUM * sizeof ( int ) ;
2018-07-11 18:59:23 +08:00
// ret=MESA_lqueue_try_get_tail(g_kni_structinfo.lqueue_for_domain,fds,&fds_len);
ret = MESA_lqueue_get_tail ( g_kni_structinfo . lqueue_for_domain , fds , & fds_len ) ;
2018-07-10 09:32:18 +08:00
if ( ret = = MESA_QUEUE_RET_QEMPTY )
{
continue ;
}
else if ( ret < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_READTUN , " MESA_lqueue_try_get_tail() error!ret:%d \n " , ret ) ;
continue ;
}
ret = kni_send_fds ( g_kni_comminfo . fd_domain , fds , 2 , fds [ KNI_FDS_INDEX_PROTOCOL ] ) ;
if ( ret < 0 ) //check errno
{
g_kni_comminfo . kni_mode_cur = KNI_MODE_BYPASS ;
return - 1 ;
}
close ( fds [ KNI_FDS_INDEX_CLIENT ] ) ;
close ( fds [ KNI_FDS_INDEX_SERVER ] ) ;
}
return 0 ;
2018-06-19 11:47:26 +08:00
}
2018-07-10 09:32:18 +08:00
int kni_connect_domain ( )
{
while ( 1 )
{
g_kni_comminfo . fd_domain = init_domain_fd ( ) ;
if ( g_kni_comminfo . fd_domain < 0 )
{
2018-07-17 10:34:26 +08:00
sleep ( 1 ) ;
2018-07-10 09:32:18 +08:00
}
else
{
g_kni_comminfo . kni_mode_cur = KNI_MODE_WORK ;
return 0 ;
}
}
2018-06-19 11:47:26 +08:00
2018-07-10 09:32:18 +08:00
return 0 ;
}
2018-06-19 11:47:26 +08:00
/********************************************************************************************************************
name :
function :
return :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-07-10 09:32:18 +08:00
void * kni_process_domain ( void * arg )
2018-06-19 11:47:26 +08:00
{
2018-07-10 09:32:18 +08:00
while ( 1 )
{
if ( g_kni_comminfo . kni_mode_cur = = KNI_MODE_BYPASS )
{
kni_connect_domain ( ) ;
}
else
{
kni_sendfds_domain ( ) ;
}
}
2018-06-19 11:47:26 +08:00
2018-07-10 09:32:18 +08:00
return 0 ;
2018-06-19 11:47:26 +08:00
}
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
int tcprepair_get_state ( struct kni_tcp_state * fake_client , struct kni_tcp_state * fake_server , void * a_packet , struct kni_pme_info * pmeinfo )
2018-06-19 11:47:26 +08:00
{
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 ) ;
2018-07-11 18:59:23 +08:00
fake_client - > mss_src = pmeinfo - > mss [ KNI_DIR_C2S ] ;
fake_client - > wscale_src = pmeinfo - > wnscal [ KNI_DIR_C2S ] ;
fake_client - > wscale_dst = pmeinfo - > wnscal [ KNI_DIR_S2C ] ;
fake_client - > sack_src = pmeinfo - > sack [ KNI_DIR_C2S ] ;
fake_client - > sack_dst = pmeinfo - > sack [ KNI_DIR_S2C ] ;
fake_client - > timestamps_src = pmeinfo - > timestamps [ KNI_DIR_C2S ] ;
fake_client - > timestamps_dst = pmeinfo - > timestamps [ KNI_DIR_S2C ] ;
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-11 18:59:23 +08:00
fake_server - > mss_src = pmeinfo - > mss [ KNI_DIR_S2C ] ;
fake_server - > wscale_src = pmeinfo - > wnscal [ KNI_DIR_S2C ] ;
fake_server - > wscale_dst = pmeinfo - > wnscal [ KNI_DIR_C2S ] ;
fake_server - > sack_src = pmeinfo - > sack [ KNI_DIR_S2C ] ;
fake_server - > sack_dst = pmeinfo - > sack [ KNI_DIR_C2S ] ;
fake_server - > timestamps_src = pmeinfo - > timestamps [ KNI_DIR_S2C ] ;
fake_server - > timestamps_dst = pmeinfo - > timestamps [ KNI_DIR_C2S ] ;
2018-06-19 11:47:26 +08:00
return 0 ;
}
2018-07-11 18:59:23 +08:00
int tcprepair_set_state ( int sk , struct kni_tcp_state * tcp )
2018-07-09 11:03:00 +08:00
{
2018-07-11 18:59:23 +08:00
int val , yes = 1 , onr = 0 ;
2018-07-17 10:18:08 +08:00
// int mark = 2;
// int mark_tmp=0;
// socklen_t mark_len=sizeof(mark_tmp);
2018-07-11 18:59:23 +08:00
struct tcp_repair_opt opts [ KNI_TCPREPAIR_OPT_NUM ] ;
struct sockaddr_in addr ;
if ( setsockopt ( sk , SOL_TCP , TCP_REPAIR , & yes , sizeof ( yes ) ) = = - 1 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() TCP_REPAIR error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
if ( setsockopt ( sk , SOL_IP , IP_TRANSPARENT , & yes , sizeof ( yes ) ) < 0 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() IP_TRANSPARENT error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
if ( setsockopt ( sk , SOL_SOCKET , SO_REUSEADDR , & yes , sizeof ( yes ) ) = = - 1 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() SO_REUSEADDR error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
2018-07-17 10:18:08 +08:00
/*
2018-07-11 18:59:23 +08:00
if ( setsockopt ( sk , SOL_SOCKET , SO_MARK , & mark , sizeof ( mark ) ) < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() SO_MARK error,errno:%d " , errno ) ;
return - 1 ;
}
2018-07-17 10:18:08 +08:00
getsockopt ( sk , SOL_SOCKET , SO_MARK , & mark_tmp , & mark_len ) ;
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " getsockopt() SO_MARK :%d " , mark_tmp ) ;
2018-07-11 18:59:23 +08:00
*/
/* ============= Restore TCP properties ==================*/
val = TCP_SEND_QUEUE ;
if ( setsockopt ( sk , SOL_TCP , TCP_REPAIR_QUEUE , & val , sizeof ( val ) ) )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() TCP_REPAIR_QUEUE,TCP_SEND_QUEUE error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
val = tcp - > seq ;
if ( setsockopt ( sk , SOL_TCP , TCP_QUEUE_SEQ , & val , sizeof ( val ) ) )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() TCP_QUEUE_SEQ error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
val = TCP_RECV_QUEUE ;
if ( setsockopt ( sk , SOL_TCP , TCP_REPAIR_QUEUE , & val , sizeof ( val ) ) )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() TCP_REPAIR_QUEUE,TCP_RECV_QUEUE error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
val = tcp - > ack ;
if ( setsockopt ( sk , SOL_TCP , TCP_QUEUE_SEQ , & val , sizeof ( val ) ) )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() TCP_QUEUE_SEQ error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
/*
struct tcp_repair_window win ;
win . snd_wl1 = tcp - > seq ;
win . snd_wnd = tcp - > wnscale [ KNI_DIR_C2S ] < < tcp - > wnscale [ KNI_DIR_S2C ] ;
win . max_window = win . snd_wnd ;
win . rcv_wnd = win . snd_wnd ;
win . rcv_wup = win . snd_wl1 ;
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
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 ;
}
*/
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
/* ============= 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 ;
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
if ( bind ( sk , ( struct sockaddr * ) & addr , sizeof ( addr ) ) )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " bind() error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
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 ) ) )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " connect() error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
opts [ onr ] . opt_code = TCPOPT_WINDOW ;
opts [ onr ] . opt_val = tcp - > wscale_src + ( tcp - > wscale_dst < < 16 ) ;
onr + + ;
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
opts [ onr ] . opt_code = TCPOPT_MAXSEG ;
opts [ onr ] . opt_val = tcp - > mss_src ;
onr + + ;
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
if ( ( tcp - > sack_src ) & & ( tcp - > sack_dst ) )
{
opts [ onr ] . opt_code = TCPOPT_SACK_PERMITTED ;
opts [ onr ] . opt_val = 0 ;
onr + + ;
}
/*
opts [ onr ] . opt_code = TCPOPT_TIMESTAMP ;
opts [ onr ] . opt_val = ( tcp - > timestamps_src ) & & ( tcp - > timestamps_dst ) ;
onr + + ;
*/
2018-07-16 15:23:21 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " onr:%d,wscale_src:%d,wscale_dst:%d,wscale:%x,mss:%d,sack:%d " , onr , tcp - > wscale_src , tcp - > wscale_dst , opts [ 0 ] . opt_val , opts [ 1 ] . opt_val , opts [ 2 ] . opt_val ) ;
2018-07-11 18:59:23 +08:00
if ( setsockopt ( sk , SOL_TCP , TCP_REPAIR_OPTIONS , opts , onr * sizeof ( struct tcp_repair_opt ) ) < 0 )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() TCP_REPAIR_OPTIONS error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
val = 0 ;
if ( setsockopt ( sk , SOL_TCP , TCP_REPAIR , & val , sizeof ( val ) ) )
{
2018-07-18 10:37:20 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " setsockopt() TCP_REPAIR close error,errno:%d,%s " , errno , strerror ( errno ) ) ;
2018-07-11 18:59:23 +08:00
return - 1 ;
}
return 0 ;
}
int tcp_repair_process ( const struct streaminfo * pstream , const struct ip * a_packet , struct kni_pme_info * pmeinfo , int protocol )
{
# ifdef KNI_DEBUG_TCPREPAIR
return 0 ;
# endif
int ret = 0 ;
int fds [ KNI_FDS_NUM ] ;
int fd_client , fd_server ;
struct kni_tcp_state fake_client ;
struct kni_tcp_state fake_server ;
struct ip * iphdr = ( struct ip * ) a_packet ;
struct tcphdr * tcphdr = ( struct tcphdr * ) ( ( char * ) a_packet + 4 * ( iphdr - > ip_hl ) ) ;
// int tcplen=ntohs(iphdr->ip_len)-4*iphdr->ip_hl-4*tcphdr->doff;
fd_client = socket ( AF_INET , SOCK_STREAM , 0 ) ;
fd_server = socket ( AF_INET , SOCK_STREAM , 0 ) ;
if ( ( fd_client < 0 ) | | ( fd_server < 0 ) )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " socket() error " ) ;
return - 1 ;
}
tcprepair_get_state ( & fake_client , & fake_server , ( void * ) a_packet , pmeinfo ) ;
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
ret = tcprepair_set_state ( fd_client , & fake_server ) ;
if ( ret < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " fd_client tcprepair_set_state() error,dropme and fwdpkt " ) ;
return - 1 ;
}
ret = tcprepair_set_state ( fd_server , & fake_client ) ;
if ( ret < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " tcprepair_set_state " , " fd_server tcprepair_set_state() error,dropme and fwdpkt " ) ;
return - 1 ;
}
fds [ 0 ] = fd_client ;
fds [ 1 ] = fd_server ;
fds [ 2 ] = protocol ;
// ret=MESA_lqueue_try_join_head(g_kni_structinfo.lqueue_for_domain,(void*)fds,KNI_FDS_NUM*sizeof(int));
ret = MESA_lqueue_join_head ( g_kni_structinfo . lqueue_for_domain , ( void * ) fds , KNI_FDS_NUM * sizeof ( int ) ) ;
if ( ret < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_SENDFD , " MESA_lqueue_try_join_head() error,ret:%d " , ret ) ;
}
/*
kni_send_fds ( g_kni_comminfo . fd_domain , fds , 2 , protocol ) ;
close ( fds [ 0 ] ) ;
close ( fds [ 1 ] ) ;
*/
2018-07-09 11:03:00 +08:00
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-07-16 15:23:21 +08:00
int kni_judge_sni ( char * sni , int sni_len , int thread_seq , scan_status_t mid )
2018-06-19 11:47:26 +08:00
{
2018-07-16 15:23:21 +08:00
int i = 0 ;
2018-07-12 17:49:00 +08:00
int action = KNI_ACTION_NONE ;
2018-07-16 15:23:21 +08:00
int state_flag = KNI_FLAG_NOTPROC ;
2018-06-19 11:47:26 +08:00
int string_scan_num = 0 ;
int found_pos ;
2018-07-16 15:23:21 +08:00
struct Maat_rule_t maat_result [ KNI_MAX_SAMENUM ] ;
2018-06-19 11:47:26 +08:00
2018-07-16 15:23:21 +08:00
string_scan_num = Maat_full_scan_string ( g_kni_maatinfo . maat_feather , g_kni_maatinfo . tableid_domain , CHARSET_GBK , sni , sni_len , maat_result , & found_pos , KNI_MAX_SAMENUM , & mid , thread_seq ) ;
for ( i = 0 ; i < string_scan_num ; i + + )
2018-06-19 11:47:26 +08:00
{
2018-07-16 15:23:21 +08:00
action = abs ( maat_result [ i ] . action ) ;
if ( action = = KNI_ACTION_WHITELIST )
2018-07-12 17:49:00 +08:00
{
state_flag = KNI_FLAG_SNIBMD ;
2018-07-16 15:23:21 +08:00
return state_flag ;
2018-07-12 17:49:00 +08:00
}
2018-06-19 11:47:26 +08:00
}
return state_flag ;
}
/***************************************************************************************
return : state_flag
ssl : STAT_FLAG_SSL_NOBMD
not ssl : STAT_FLAG_NOTSSL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-07-11 18:59:23 +08:00
/*
int kni_judge_ssl_bak ( char * tcp_data , int tcp_datalen , char * sni , int * sni_len )
2018-06-19 11:47:26 +08:00
{
2018-07-12 17:49:00 +08:00
// int state_flag=KNI_FLAG_UNKNOW;
2018-07-11 18:59:23 +08:00
// return STAT_FLAG_SSL_NOBMD;
2018-06-19 11:47:26 +08:00
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 ;
}
2018-07-11 18:59:23 +08:00
*/
2018-06-19 11:47:26 +08:00
/***************************************************************************************
2018-07-12 17:49:00 +08:00
return : action
default : ipscan_num = 0 or = 1 , not > 1
2018-06-19 11:47:26 +08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-07-16 15:23:21 +08:00
int kni_judge_ipbmd ( struct ipaddr * addr , int thread_seq , int protocol , scan_status_t mid )
2018-06-19 11:47:26 +08:00
{
2018-07-16 15:23:21 +08:00
int i = 0 ;
2018-07-12 17:49:00 +08:00
int action = KNI_ACTION_NONE ;
2018-06-19 11:47:26 +08:00
int ipscan_num = 0 ;
2018-07-16 15:23:21 +08:00
struct Maat_rule_t maat_result [ KNI_MAX_SAMENUM ] ;
2018-06-19 11:47:26 +08:00
2018-07-16 15:23:21 +08:00
ipscan_num = Maat_scan_proto_addr ( g_kni_maatinfo . maat_feather , g_kni_maatinfo . tableid_ip , addr , protocol , maat_result , KNI_MAX_SAMENUM , & mid , thread_seq ) ;
2018-06-19 11:47:26 +08:00
2018-07-16 15:23:21 +08:00
for ( i = 0 ; i < ipscan_num ; i + + )
2018-06-19 11:47:26 +08:00
{
2018-07-16 15:23:21 +08:00
action = abs ( maat_result [ i ] . action ) ;
if ( action = = KNI_ACTION_WHITELIST )
{
return action ;
}
2018-06-19 11:47:26 +08:00
}
2018-07-12 17:49:00 +08:00
return action ;
2018-06-19 11:47:26 +08:00
}
2018-07-11 18:59:23 +08:00
int kni_get_tcpinfo ( struct kni_wndpro_reply_info * lastpkt_info , struct kni_tcp_hdr * tcphdr , int tcplen , struct ip * ip_hdr )
{
lastpkt_info - > seq = ntohl ( tcphdr - > th_seq ) ;
lastpkt_info - > ack = ntohl ( tcphdr - > th_ack ) ;
lastpkt_info - > ipid = ntohs ( ip_hdr - > ip_id ) ;
lastpkt_info - > ttl = ip_hdr - > ip_ttl ;
lastpkt_info - > len = tcplen ;
lastpkt_info - > wndsize = ntohs ( tcphdr - > th_win ) ;
if ( tcphdr - > th_flags & TH_SYN )
{
lastpkt_info - > syn_flag = 1 ;
}
return 0 ;
}
int kni_get_tcpopt ( struct kni_tcp_hdr * tcphdr , int tcp_hdr_len , unsigned short * mss , unsigned char * winscale , unsigned char * scak , unsigned char * timestamps )
2018-06-19 11:47:26 +08:00
{
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
* mss = KNI_DEFAULT_MSS ;
* winscale = KNI_DEFAULT_WINSCLE ;
2018-06-19 11:47:26 +08:00
int remain_len = tcp_hdr_len ;
2018-07-11 18:59:23 +08:00
struct kni_tcp_opt_format * tcp_opt = NULL ;
2018-06-19 11:47:26 +08:00
if ( ( tcp_hdr_len < = 20 ) | | ( tcp_hdr_len > 64 ) )
{
2018-07-11 18:59:23 +08:00
return 0 ;
2018-06-19 11:47:26 +08:00
}
2018-07-11 18:59:23 +08:00
tcp_opt = ( struct kni_tcp_opt_format * ) ( ( char * ) tcphdr + TCPHDR_DEFAULT_LEN ) ;
2018-06-19 11:47:26 +08:00
remain_len - = TCPHDR_DEFAULT_LEN ;
while ( remain_len )
{
2018-07-11 18:59:23 +08:00
if ( tcp_opt - > type = = KNI_TCPOPT_MSS ) //MSS
2018-07-10 16:04:54 +08:00
{
2018-07-11 18:59:23 +08:00
remain_len - = tcp_opt - > len ;
* mss = htons ( * ( unsigned short * ) ( tcp_opt - > content ) ) ;
tcp_opt = ( struct kni_tcp_opt_format * ) ( ( char * ) tcp_opt + tcp_opt - > len ) ;
2018-07-16 15:23:21 +08:00
continue ;
2018-07-11 18:59:23 +08:00
}
else if ( tcp_opt - > type = = KNI_TCPOPT_WINSCALE ) //winscale
{
remain_len - = tcp_opt - > len ;
* winscale = * ( unsigned char * ) ( tcp_opt - > content ) ;
tcp_opt = ( struct kni_tcp_opt_format * ) ( ( char * ) tcp_opt + tcp_opt - > len ) ;
2018-07-16 15:23:21 +08:00
continue ;
2018-07-11 18:59:23 +08:00
}
else if ( tcp_opt - > type = = KNI_TCPOPT_SACKOK ) //scak
{
remain_len - = tcp_opt - > len ;
* scak = 1 ;
tcp_opt = ( struct kni_tcp_opt_format * ) ( ( char * ) tcp_opt + tcp_opt - > len ) ;
2018-07-16 15:23:21 +08:00
continue ;
2018-07-11 18:59:23 +08:00
}
else if ( tcp_opt - > type = = KNI_TCPOPT_TIMESTAMP ) //timestamp
{
remain_len - = tcp_opt - > len ;
* timestamps = 1 ;
tcp_opt = ( struct kni_tcp_opt_format * ) ( ( char * ) tcp_opt + tcp_opt - > len ) ;
2018-07-16 15:23:21 +08:00
continue ;
2018-07-10 16:04:54 +08:00
}
2018-06-19 11:47:26 +08:00
else if ( ( tcp_opt - > type = = 0 ) | | ( tcp_opt - > type = = 1 ) )
{
remain_len - = 1 ;
2018-07-11 18:59:23 +08:00
tcp_opt = ( struct kni_tcp_opt_format * ) ( ( char * ) tcp_opt + 1 ) ;
2018-07-16 15:23:21 +08:00
continue ;
2018-06-19 11:47:26 +08:00
}
else
{
remain_len - = tcp_opt - > len ;
2018-07-11 18:59:23 +08:00
tcp_opt = ( struct kni_tcp_opt_format * ) ( ( char * ) tcp_opt + tcp_opt - > len ) ;
2018-07-16 15:23:21 +08:00
continue ;
2018-06-19 11:47:26 +08:00
}
}
2018-07-11 18:59:23 +08:00
return 0 ;
2018-06-19 11:47:26 +08:00
}
2018-07-12 17:49:00 +08:00
char * kni_get_data ( const struct streaminfo * pstream , int * datalen )
2018-07-11 18:59:23 +08:00
{
2018-07-12 17:49:00 +08:00
char * data = NULL ;
2018-07-11 18:59:23 +08:00
if ( pstream - > type = = STREAM_TYPE_TCP )
{
data = ( char * ) ( pstream - > ptcpdetail - > pdata ) ;
* datalen = pstream - > ptcpdetail - > datalen ;
}
else if ( pstream - > type = = STREAM_TYPE_UDP )
{
data = ( char * ) ( pstream - > pudpdetail - > pdata ) ;
* datalen = pstream - > pudpdetail - > datalen ;
}
else
{
data = NULL ;
* datalen = 0 ;
}
2018-07-11 17:22:51 +08:00
2018-07-12 17:49:00 +08:00
return data ;
2018-07-11 18:59:23 +08:00
}
int kni_htable_add ( const struct streaminfo * pstream , const struct ip * ip_hdr , struct kni_pme_info * pmeinfo )
{
int iprevers = 0 ;
struct stream_tuple4_v4 ipv4_addr ;
struct layer_addr_mac * mac_addr = ( struct layer_addr_mac * ) ( ( char * ) ip_hdr - KNI_ETHER_LEN ) ;
struct kni_htable_datainfo * datainfo = ( struct kni_htable_datainfo * ) malloc ( sizeof ( struct kni_htable_datainfo ) ) ;
memset ( datainfo , 0 , sizeof ( struct kni_htable_datainfo ) ) ;
iprevers = kni_get_ipaddr_v4 ( ( void * ) ip_hdr , & ipv4_addr ) ;
//send pkt info
if ( iprevers = = 0 )
{
datainfo - > route_dir = pstream - > routedir ;
memcpy ( datainfo - > smac , mac_addr - > src_mac , MAC_ADDR_LEN ) ;
memcpy ( datainfo - > dmac , mac_addr - > dst_mac , MAC_ADDR_LEN ) ;
}
else
{
2018-07-18 10:37:20 +08:00
// datainfo->route_dir=MESA_dir_reverse(pstream->routedir);
datainfo - > route_dir = 1 - pstream - > routedir ;
2018-07-11 18:59:23 +08:00
memcpy ( datainfo - > smac , mac_addr - > dst_mac , MAC_ADDR_LEN ) ;
memcpy ( datainfo - > dmac , mac_addr - > src_mac , MAC_ADDR_LEN ) ;
}
//send wnd_pro_reply info
memcpy ( datainfo - > wnscal , pmeinfo - > wnscal , KNI_DIR_DOUBLE * sizeof ( unsigned char ) ) ;
memcpy ( datainfo - > mss , pmeinfo - > mss , KNI_DIR_DOUBLE * sizeof ( unsigned short ) ) ;
memcpy ( & ( datainfo - > lastpkt_info ) , & ( pmeinfo - > lastpkt_info ) , KNI_DIR_DOUBLE * sizeof ( struct kni_wndpro_reply_info ) ) ;
MESA_htable_add ( g_kni_structinfo . htable_to_tun_v4 , ( unsigned char * ) & ipv4_addr , sizeof ( struct stream_tuple4_v4 ) , ( void * ) datainfo ) ;
return 0 ;
}
/***************************************************************************************
return : state_flag
ssl : STAT_FLAG_SSL_NOBMD
not ssl : STAT_FLAG_NOTSSL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int kni_judge_ssl ( char * tcp_data , int tcp_datalen , char * sni , int * sni_len )
2018-07-10 09:32:18 +08:00
{
2018-07-12 17:49:00 +08:00
// int state_flag=KNI_FLAG_UNKNOW;
2018-07-11 18:59:23 +08:00
// return KNI_FLAG_SSL;
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
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 ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
//ssl header
ssl_header = tcp_data ;
content_type = * ( unsigned char * ) & ssl_header [ ssl_header_len ] ;
if ( content_type ! = SSL_CONTENTTYPE_HANDSHAKE )
{
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
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 ) )
{
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
ssl_header_len + = 2 ;
len_in_header = ntohs ( * ( unsigned short * ) & ( ssl_header [ ssl_header_len ] ) ) ;
if ( len_in_header ! = tcp_datalen - SSL_HEADER_LEN )
{
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
ssl_header_len + = 2 ;
2018-07-11 17:22:51 +08:00
2018-07-11 18:59:23 +08:00
//ssl body
ssl_body = ssl_header + ssl_header_len ;
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
handshark_type = * ( unsigned char * ) & ( ssl_body [ ssl_body_len ] ) ;
if ( handshark_type ! = SSL_HANDSHAR_TYPE_CLIENTHELLO )
2018-07-10 09:32:18 +08:00
{
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
ssl_body_len + = 1 ;
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
// 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 ) )
{
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
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 ) )
{
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
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 ;
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
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 ;
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
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 )
{
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
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 )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
if ( len_in_extension > KNI_SNI_MAXLEN )
{
//error
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
memcpy ( sni , & ssl_extention [ ssl_extention_len ] , len_in_extension ) ;
* sni_len = len_in_extension ;
return KNI_FLAG_SSL ;
2018-06-19 11:47:26 +08:00
}
else
{
2018-07-11 18:59:23 +08:00
ssl_extention_len + = len_in_extension ;
continue ;
2018-07-09 11:03:00 +08:00
}
2018-07-11 18:59:23 +08:00
}
2018-07-12 17:49:00 +08:00
return KNI_FLAG_UNKNOW ;
2018-07-11 18:59:23 +08:00
}
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
int kni_judge_http ( const struct streaminfo * stream )
{
int val = project_req_get_int ( stream , g_kni_comminfo . project_id ) ;
return val ;
}
int kni_protocol_identify ( const struct streaminfo * pstream , char * tcp_data , int tcp_datalen , char * sni , int * sni_len )
{
if ( kni_judge_http ( pstream ) = = 1 )
{
return KNI_FLAG_HTTP ;
}
else if ( kni_judge_ssl ( tcp_data , tcp_datalen , sni , sni_len ) = = KNI_FLAG_SSL )
{
return KNI_FLAG_SSL ;
2018-07-09 11:03:00 +08:00
}
2018-07-11 18:59:23 +08:00
return KNI_FLAG_NOTPROC ;
}
2018-07-17 10:18:08 +08:00
int kni_protocol_identify_bak ( const struct streaminfo * pstream , char * tcp_data , int tcp_datalen , char * sni , int * sni_len )
2018-07-11 18:59:23 +08:00
{
int pro_flag = KNI_FLAG_NOTPROC ;
unsigned short sport = ntohs ( pstream - > addr . tuple4_v4 - > source ) ;
unsigned short dport = ntohs ( pstream - > addr . tuple4_v4 - > dest ) ;
if ( ( sport = = 80 ) | | ( dport = = 80 ) )
2018-07-09 11:03:00 +08:00
{
2018-07-11 18:59:23 +08:00
pro_flag = KNI_FLAG_HTTP ;
2018-07-09 11:03:00 +08:00
}
2018-07-17 10:18:08 +08:00
else if ( kni_judge_ssl ( tcp_data , tcp_datalen , sni , sni_len ) = = KNI_FLAG_SSL )
2018-07-11 18:59:23 +08:00
{
2018-07-17 10:18:08 +08:00
pro_flag = KNI_FLAG_SSL ;
2018-07-11 18:59:23 +08:00
}
return pro_flag ;
}
2018-07-09 11:03:00 +08:00
2018-07-11 18:59:23 +08:00
char kni_first_tcpdata ( const struct streaminfo * pstream , const struct ip * ip_hdr , struct kni_pme_info * pmeinfo , char * data , int datalen )
{
char ret = APP_STATE_FAWPKT | APP_STATE_DROPME ;
int sni_len = 0 ;
char sni [ KNI_MAX_BUFLEN ] = { 0 } ;
2018-07-12 17:49:00 +08:00
pmeinfo - > status_flag = kni_protocol_identify ( pstream , data , datalen , sni , & sni_len ) ;
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_DEBUG , ( char * ) " kni_protocol_identify " , " protocol:%d " , pmeinfo - > status_flag ) ;
2018-07-11 18:59:23 +08:00
if ( pmeinfo - > status_flag = = KNI_FLAG_SSL )
{
2018-07-16 15:23:21 +08:00
pmeinfo - > status_flag = kni_judge_sni ( sni , sni_len , pstream - > threadnum , pmeinfo - > mid ) ;
2018-07-12 17:49:00 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_DEBUG , ( char * ) " kni_judge_sni " , " status_flag:%d " , pmeinfo - > status_flag ) ;
2018-07-11 18:59:23 +08:00
}
if ( ( pmeinfo - > status_flag = = KNI_FLAG_HTTP ) | | ( pmeinfo - > status_flag = = KNI_FLAG_SSL ) )
{
if ( tcp_repair_process ( pstream , ip_hdr , pmeinfo , pmeinfo - > status_flag ) < 0 )
{
return ret ;
}
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
kni_htable_add ( pstream , ip_hdr , pmeinfo ) ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
ret = APP_STATE_DROPPKT | APP_STATE_GIVEME ;
}
return ret ;
}
2018-07-16 15:23:21 +08:00
int kni_init_pmeinfo ( void * * pme )
{
struct kni_pme_info * pmeinfo = ( struct kni_pme_info * ) malloc ( sizeof ( struct kni_pme_info ) ) ;
memset ( pmeinfo , 0 , sizeof ( struct kni_pme_info ) ) ;
* pme = pmeinfo ;
return 0 ;
}
int kni_free_pmeinfo ( void * * pme )
{
struct kni_pme_info * pmeinfo = ( struct kni_pme_info * ) * pme ;
Maat_clean_status ( & ( pmeinfo - > mid ) ) ;
free ( pmeinfo ) ;
pmeinfo = NULL ;
return 0 ;
}
char kni_pending_opstate ( const struct streaminfo * pstream , struct kni_pme_info * pmeinfo , int thread_seq , const struct ip * ip_hdr , int protocol )
2018-07-11 18:59:23 +08:00
{
char ret = APP_STATE_FAWPKT | APP_STATE_DROPME ;
char * data = NULL ;
int datalen = 0 ;
int ipscan_action = 0 ;
int iplen = ntohs ( ip_hdr - > ip_len ) ;
struct kni_tcp_hdr * tcphdr = ( struct kni_tcp_hdr * ) ( ( char * ) ip_hdr + 4 * ( ip_hdr - > ip_hl ) ) ;
2018-07-16 15:23:21 +08:00
ipscan_action = kni_judge_ipbmd ( ( struct ipaddr * ) & ( pstream - > addr ) , thread_seq , protocol , pmeinfo - > mid ) ;
2018-07-12 17:49:00 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_DEBUG , ( char * ) " kni_judge_ipbmd " , " action:%d " , ipscan_action ) ;
2018-07-16 15:23:21 +08:00
if ( ipscan_action = = KNI_ACTION_WHITELIST )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
return ret ;
}
pmeinfo - > status_flag = KNI_FLAG_UNKNOW ;
// pmeinfo->wndsize[pstream->curdir-1]=ntohs(tcphdr->th_win);
// if((tcphdr->th_flags&TH_SYN)&&!(tcphdr->th_flags&TH_ACK)) //get wndscale and mss from tcpopt only in syn and syn/ack
{
2018-07-12 17:49:00 +08:00
data = kni_get_data ( pstream , & datalen ) ;
2018-07-11 18:59:23 +08:00
kni_get_tcpopt ( tcphdr , iplen - 4 * ( ip_hdr - > ip_hl ) - datalen , & ( pmeinfo - > mss [ pstream - > curdir - 1 ] ) , & ( pmeinfo - > wnscal [ pstream - > curdir - 1 ] ) , & ( pmeinfo - > sack [ pstream - > curdir - 1 ] ) , & ( pmeinfo - > timestamps [ pstream - > curdir - 1 ] ) ) ;
}
kni_get_tcpinfo ( & ( pmeinfo - > lastpkt_info [ pstream - > curdir - 1 ] ) , tcphdr , ntohs ( ip_hdr - > ip_len ) - 4 * ip_hdr - > ip_hl - 4 * tcphdr - > th_off , ( struct ip * ) ip_hdr ) ;
# ifndef KNI_DEBUG_TCPREPAIR
if ( datalen > 0 )
# endif
{
ret = kni_first_tcpdata ( pstream , ip_hdr , pmeinfo , data , datalen ) ;
if ( ( pmeinfo - > status_flag = = KNI_FLAG_HTTP ) | | ( pmeinfo - > status_flag = = KNI_FLAG_SSL ) )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
ret = tun_write_data ( g_kni_comminfo . fd_tun [ thread_seq ] , ( char * ) ip_hdr , iplen , ( struct streaminfo * ) pstream ) ;
2018-06-19 11:47:26 +08:00
}
}
2018-07-11 18:59:23 +08:00
# ifndef KNI_DEBUG_TCPREPAIR
else
{
ret = APP_STATE_FAWPKT | APP_STATE_GIVEME ;
}
# endif
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
return ret ;
2018-06-19 11:47:26 +08:00
}
2018-07-16 15:23:21 +08:00
char kni_data_opstate ( const struct streaminfo * pstream , struct kni_pme_info * pmeinfo , int thread_seq , const struct ip * ip_hdr )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
char ret = APP_STATE_DROPPKT | APP_STATE_GIVEME ;
char * data = NULL ;
int datalen = 0 ;
int iplen = ntohs ( ip_hdr - > ip_len ) ;
2018-07-16 15:23:21 +08:00
// struct kni_pme_info* pmeinfo=(struct kni_pme_info*)*pme;
2018-07-11 18:59:23 +08:00
struct kni_tcp_hdr * tcphdr = ( struct kni_tcp_hdr * ) ( ( char * ) ip_hdr + 4 * ( ip_hdr - > ip_hl ) ) ;
2018-07-12 17:49:00 +08:00
data = kni_get_data ( pstream , & datalen ) ;
2018-07-11 17:22:51 +08:00
2018-07-11 18:59:23 +08:00
if ( pmeinfo - > status_flag = = KNI_FLAG_UNKNOW )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
if ( ( tcphdr - > th_flags & TH_SYN ) & & ( tcphdr - > th_flags & TH_ACK ) )
{
kni_get_tcpopt ( tcphdr , iplen - 4 * ( ip_hdr - > ip_hl ) - datalen , & ( pmeinfo - > mss [ pstream - > curdir - 1 ] ) , & ( pmeinfo - > wnscal [ pstream - > curdir - 1 ] ) , & ( pmeinfo - > sack [ pstream - > curdir - 1 ] ) , & ( pmeinfo - > timestamps [ pstream - > curdir - 1 ] ) ) ;
}
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
kni_get_tcpinfo ( & ( pmeinfo - > lastpkt_info [ pstream - > curdir - 1 ] ) , tcphdr , ntohs ( ip_hdr - > ip_len ) - 4 * ip_hdr - > ip_hl - 4 * tcphdr - > th_off , ( struct ip * ) ip_hdr ) ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
if ( datalen > 0 )
{
ret = kni_first_tcpdata ( pstream , ip_hdr , pmeinfo , data , datalen ) ;
}
else
{
ret = APP_STATE_FAWPKT | APP_STATE_GIVEME ;
}
2018-06-19 11:47:26 +08:00
}
2018-07-11 18:59:23 +08:00
if ( ( pmeinfo - > status_flag = = KNI_FLAG_HTTP ) | | ( pmeinfo - > status_flag = = KNI_FLAG_SSL ) )
{
ret = tun_write_data ( g_kni_comminfo . fd_tun [ thread_seq ] , ( char * ) ip_hdr , iplen , ( struct streaminfo * ) pstream ) ;
}
return ret ;
2018-06-19 11:47:26 +08:00
}
2018-07-16 15:23:21 +08:00
char kni_close_opstate ( const struct streaminfo * pstream , struct kni_pme_info * pmeinfo , int thread_seq , const struct ip * ip_hdr )
2018-06-19 11:47:26 +08:00
{
2018-07-11 18:59:23 +08:00
char ret = APP_STATE_FAWPKT | APP_STATE_DROPME ;
if ( ip_hdr = = NULL )
2018-07-10 09:32:18 +08:00
{
return ret ;
2018-07-09 11:03:00 +08:00
}
2018-07-16 15:23:21 +08:00
ret = kni_data_opstate ( pstream , pmeinfo , thread_seq , ip_hdr ) ;
2018-07-11 14:51:29 +08:00
2018-07-11 18:59:23 +08:00
return ret | APP_STATE_DROPME ;
}
extern " C " char kni_tcpall_entry ( const struct streaminfo * pstream , void * * pme , int thread_seq , const void * ip_hdr )
{
// return APP_STATE_FAWPKT|APP_STATE_GIVEME;
char ret = APP_STATE_FAWPKT | APP_STATE_DROPME ;
2018-07-17 10:18:08 +08:00
if ( ( g_kni_comminfo . kni_mode_cur = = KNI_MODE_BYPASS ) | | ( pstream - > addr . addrtype = = ADDR_TYPE_IPV6 ) )
2018-06-19 11:47:26 +08:00
{
return ret ;
}
2018-07-17 10:18:08 +08:00
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
switch ( pstream - > pktstate )
{
case OP_STATE_PENDING :
2018-07-16 15:23:21 +08:00
kni_init_pmeinfo ( pme ) ;
ret = kni_pending_opstate ( pstream , ( struct kni_pme_info * ) * pme , thread_seq , ( const struct ip * ) ip_hdr , PROTO_TYPE_TCP ) ;
2018-07-11 18:59:23 +08:00
break ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
case OP_STATE_DATA :
2018-07-16 15:23:21 +08:00
ret = kni_data_opstate ( pstream , ( struct kni_pme_info * ) * pme , thread_seq , ( const struct ip * ) ip_hdr ) ;
2018-07-11 18:59:23 +08:00
break ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
case OP_STATE_CLOSE :
2018-07-16 15:23:21 +08:00
ret = kni_close_opstate ( pstream , ( struct kni_pme_info * ) * pme , thread_seq , ( const struct ip * ) ip_hdr ) ;
2018-07-11 18:59:23 +08:00
break ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
default :
break ;
2018-06-19 11:47:26 +08:00
}
2018-07-11 18:59:23 +08:00
if ( ( ret & APP_STATE_DROPME ) & & ( * pme ! = NULL ) )
2018-06-19 11:47:26 +08:00
{
2018-07-16 15:23:21 +08:00
kni_free_pmeinfo ( pme ) ;
2018-07-11 18:59:23 +08:00
* pme = NULL ;
2018-06-19 11:47:26 +08:00
}
2018-07-11 18:59:23 +08:00
return ret ;
}
2018-07-16 15:23:21 +08:00
/*
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +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 datainfo_to_tun * datainfo = ( struct datainfo_to_tun * ) data ;
struct args_to_tun * arg = ( struct args_to_tun * ) user_arg ;
struct kni_ipv6_hdr * ipv6_hdr = ( struct kni_ipv6_hdr * ) ( arg - > a_packet ) ;
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 ) ;
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
memset ( & addr_ipbmd , 0 , sizeof ( struct ipaddr ) ) ;
addr_ipbmd . addrtype = ADDR_TYPE_IPV6 ;
addr_ipbmd . v4 = ( struct stream_tuple4_v4 * ) key ;
2018-07-10 09:32:18 +08:00
2018-07-11 18:59:23 +08:00
datainfo - > state_flag = kni_judge_ipbmd ( & addr_ipbmd , arg - > thread_seq , ipv6_hdr - > ip6_nex_hdr ) ;
2018-06-19 11:47:26 +08:00
}
2018-07-11 18:59:23 +08:00
return datainfo - > state_flag ;
2018-07-10 09:32:18 +08:00
}
2018-06-19 11:47:26 +08:00
2018-07-16 15:23:21 +08:00
2018-06-19 11:47:26 +08:00
char kni_ipv6_entry ( struct streaminfo * pstream , unsigned char routedir , int thread_seq , void * a_packet )
{
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 ) ;
2018-07-11 18:59:23 +08:00
if ( state_flag = = KNI_FLAG_IPBMD )
2018-06-19 11:47:26 +08:00
{
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 ;
}
2018-07-12 17:49:00 +08:00
*/
2018-07-11 18:59:23 +08:00
extern " C " char kni_http_entry ( stSessionInfo * session_info , void * * pme , int thread_seq , struct streaminfo * a_stream , const void * a_packet )
{
char ret = PROT_STATE_DROPME ;
int val = 1 ;
project_req_add_int ( a_stream , g_kni_comminfo . project_id , val ) ;
return ret ;
}
2018-06-19 11:47:26 +08:00
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 )
{
2018-07-17 10:18:08 +08:00
//main.conf
// MESA_load_profile_int_def((char*)KNI_CONF_FILENAME_MAIN,(char*)KNI_CONF_MODE,(char*)"thread_num",&(g_kni_comminfo.thread_num),1);
MESA_load_profile_string_def ( ( char * ) KNI_CONF_FILENAME_MAIN , ( char * ) KNI_CONF_MODE , ( char * ) " pcapdevice " , g_kni_comminfo . card_in , KNI_CONF_MAXLEN , " cap0 " ) ;
MESA_load_profile_string_def ( ( char * ) KNI_CONF_FILENAME_MAIN , ( char * ) KNI_CONF_MODE , ( char * ) " pcapdevice2 " , g_kni_comminfo . card_out , KNI_CONF_MAXLEN , " cap1 " ) ;
2018-06-19 11:47:26 +08:00
2018-07-17 10:18:08 +08:00
//kni.conf
MESA_load_profile_int_def ( ( char * ) KNI_CONF_FILENAME , ( char * ) KNI_CONF_MODE , ( char * ) " default_switch " , & ( g_kni_switch_info . maat_default_switch ) , 1 ) ;
2018-06-19 11:47:26 +08:00
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 ) ;
2018-07-17 10:18:08 +08:00
MESA_load_profile_string_def ( ( char * ) KNI_CONF_FILENAME , ( char * ) KNI_CONF_MODE , ( char * ) " tun_name " , g_kni_comminfo . tun_name , KNI_CONF_MAXLEN , " tun0 " ) ;
MESA_load_profile_string_def ( ( char * ) KNI_CONF_FILENAME , ( char * ) KNI_CONF_MODE , ( char * ) " domain_path " , g_kni_comminfo . domain_path , KNI_CONF_MAXLEN , " /home/server_unixsocket_file " ) ;
2018-06-19 11:47:26 +08:00
return 0 ;
}
int init_kni_stat_htable ( )
{
MESA_htable_create_args_t hash_frags ;
memset ( & hash_frags , 0 , sizeof ( MESA_htable_create_args_t ) ) ;
hash_frags . thread_safe = KNI_THREAD_SAFE ;
hash_frags . recursive = 1 ;
hash_frags . hash_slot_size = KNI_HTABLE_SIZE ;
hash_frags . max_elem_num = KNI_HTABLE_MAXNUM ;
hash_frags . eliminate_type = HASH_ELIMINATE_ALGO_FIFO ;
hash_frags . expire_time = 0 ;
hash_frags . key_comp = NULL ;
hash_frags . key2index = NULL ;
hash_frags . data_free = NULL ;
hash_frags . data_expire_with_condition = NULL ;
g_kni_structinfo . htable_to_tun_v4 = MESA_htable_create ( & hash_frags , sizeof ( MESA_htable_create_args_t ) ) ;
g_kni_structinfo . htable_to_tun_v6 = MESA_htable_create ( & hash_frags , sizeof ( MESA_htable_create_args_t ) ) ;
if ( ( g_kni_structinfo . htable_to_tun_v4 = = NULL ) | | ( g_kni_structinfo . htable_to_tun_v6 = = NULL ) )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " MESA_htable_create() error!action:%s " , KNI_ACTION_EXIT ) ;
return - 1 ;
}
return 0 ;
}
2018-07-18 10:37:20 +08:00
int kni_read_cardname ( )
{
int offset = 0 ;
char * token = NULL ;
char buf [ KNI_CONF_MAXLEN ] = { 0 } ;
int routdir = 0 ;
FILE * fp = fopen ( " ./conf/send_raw_pkt.conf " , " r " ) ;
if ( fp = = NULL )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " kni_read_cardname " , " fopen ./conf/send_raw_pkt.conf err,errno:%d,%s " , errno , strerror ( errno ) ) ;
return - 1 ;
}
while ( feof ( fp ) = = 0 )
{
routdir = 0 ;
memset ( buf , 0 , KNI_CONF_MAXLEN ) ;
if ( ( fgets ( buf , KNI_CONF_MAXLEN , fp ) = = NULL ) )
{
break ;
}
if ( buf [ 0 ] = = ' # ' )
{
continue ;
}
token = strtok ( buf , " \t , " ) ;
offset = 1 ;
while ( token ! = NULL )
{
switch ( offset )
{
case KNI_OFFSET_ROUTDIR :
routdir = atoi ( token ) ;
if ( ( routdir ! = 0 ) & & ( routdir ! = 1 ) )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " kni_read_cardname " , " routdir :%d error " , routdir ) ;
return - 1 ;
}
break ;
case KNI_OFFSET_CARDNAME :
memcpy ( g_kni_cardname [ routdir ] , token , strlen ( token ) ) ;
break ;
default :
break ;
}
token = strtok ( NULL , " \t , " ) ;
offset + + ;
}
}
fclose ( fp ) ;
fp = NULL ;
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , " kni_read_cardname " , " card name:%s,%s " , g_kni_cardname [ 0 ] , g_kni_cardname [ 1 ] ) ;
return 0 ;
}
2018-06-19 11:47:26 +08:00
extern " C " char kni_init ( )
{
2018-07-12 17:49:00 +08:00
2018-06-19 11:47:26 +08:00
int i = 0 ;
int ret = 0 ;
2018-07-17 10:18:08 +08:00
// char __tun_symbol[512] = "tun0";
2018-06-19 11:47:26 +08:00
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_read_tun ;
2018-07-10 09:32:18 +08:00
pthread_t pid_pro_domain ;
2018-07-11 18:59:23 +08:00
// pthread_t pid_kni_filestat2;
2018-07-10 09:32:18 +08:00
2018-06-19 11:47:26 +08:00
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 ;
}
2018-07-11 18:59:23 +08:00
//project
2018-07-11 17:22:51 +08:00
2018-07-11 18:59:23 +08:00
g_kni_comminfo . project_id = project_producer_register ( KNI_PROJECT_NAME , PROJECT_VAL_TYPE_INT , NULL ) ;
if ( g_kni_comminfo . project_id < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " project_producer_register() error!project_id:%d " , g_kni_comminfo . project_id ) ;
return - 1 ;
}
g_kni_comminfo . project_id = project_customer_register ( KNI_PROJECT_NAME , PROJECT_VAL_TYPE_INT ) ;
if ( g_kni_comminfo . project_id < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " project_customer_register() error!project_id:%d " , g_kni_comminfo . project_id ) ;
return - 1 ;
}
2018-07-10 09:32:18 +08:00
2018-06-19 11:47:26 +08:00
//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 ;
}
2018-07-12 17:49:00 +08:00
g_kni_maatinfo . tableid_ip = Maat_table_register ( g_kni_maatinfo . maat_feather , KNI_TABLENAME_IP ) ;
g_kni_maatinfo . tableid_domain = Maat_table_register ( g_kni_maatinfo . maat_feather , KNI_TABLENAME_DOMAIN ) ;
if ( ( g_kni_maatinfo . tableid_ip < 0 ) | | ( g_kni_maatinfo . tableid_domain < 0 ) )
2018-06-19 11:47:26 +08:00
{
2018-07-12 17:49:00 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " Maat_table_register() error!ip_tableid:%d,sni_tableid:%d,action:%s " , g_kni_maatinfo . tableid_ip , g_kni_maatinfo . tableid_domain , KNI_ACTION_EXIT ) ;
2018-06-19 11:47:26 +08:00
return - 1 ;
}
//init htable
ret = init_kni_stat_htable ( ) ;
if ( ret < 0 )
{
return - 1 ;
}
2018-07-11 18:59:23 +08:00
//init lqueue for send fds
g_kni_structinfo . lqueue_for_domain = MESA_lqueue_create ( KNI_THREAD_SAFE , KNI_LQUEUE_MAXNUM ) ;
if ( g_kni_structinfo . lqueue_for_domain = = NULL )
{
printf ( " MESA_lqueue_create() error! \n " ) ;
return - 1 ;
}
2018-06-19 11:47:26 +08:00
//init tun
2018-07-17 10:18:08 +08:00
g_kni_comminfo . thread_num = g_iThreadNum ;
2018-06-19 11:47:26 +08:00
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-10 09:32:18 +08:00
memset ( g_kni_comminfo . fd_tun , 0 , sizeof ( g_kni_comminfo . thread_num * sizeof ( int ) ) ) ;
2018-06-19 11:47:26 +08:00
2018-07-17 10:18:08 +08:00
ret = tun_alloc_mq ( g_kni_comminfo . tun_name , g_kni_comminfo . thread_num , g_kni_comminfo . fd_tun ) ;
2018-06-19 11:47:26 +08:00
if ( ret < 0 )
{
return - 1 ;
}
2018-07-11 18:59:23 +08:00
// 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");
2018-06-19 11:47:26 +08:00
2018-07-11 18:59:23 +08:00
# ifndef KNI_DEBUG_TCPREPAIR
2018-06-19 11:47:26 +08:00
//init domain
g_kni_comminfo . fd_domain = init_domain_fd ( ) ;
if ( g_kni_comminfo . fd_domain < 0 )
{
2018-07-10 09:32:18 +08:00
g_kni_comminfo . kni_mode_cur = KNI_MODE_BYPASS ;
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " init_domain_fd()error " ) ;
2018-06-19 11:47:26 +08:00
}
2018-07-11 18:59:23 +08:00
pthread_create ( & pid_pro_domain , NULL , kni_process_domain , NULL ) ;
// pthread_create(&pid_kni_filestat2,NULL,kni_filestat2,NULL);
# endif
2018-07-11 17:22:51 +08:00
2018-07-11 18:59:23 +08:00
//test init raw_socket
2018-07-18 10:37:20 +08:00
kni_read_cardname ( ) ;
2018-06-19 11:47:26 +08:00
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 ;
}
2018-07-11 18:59:23 +08:00
g_kni_threadseq [ i ] = i ;
2018-07-11 17:22:51 +08:00
2018-07-11 18:59:23 +08:00
pthread_create ( & pid_read_tun , NULL , kni_read_tun , & ( g_kni_threadseq [ i ] ) ) ;
2018-07-11 17:22:51 +08:00
}
2018-07-11 18:59:23 +08:00
2018-06-19 11:47:26 +08:00
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " KNI_INIT succ! " ) ;
return 0 ;
}