2018-06-19 11:47:26 +08:00
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# 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>
# 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 ;
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 ) ;
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 ) ;
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 ) ) ;
ifr . ifr_flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE ;
if ( * dev )
{
strncpy ( ifr . ifr_name , dev , IFNAMSIZ ) ;
}
for ( i = 0 ; i < queues ; i + + )
{
if ( ( fd = open ( clonedev , O_RDWR ) ) < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " tun_alloc_mq():open error,errno is:%d,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 )
{
printf ( " tun_read_data error,msg is: %s \n " , strerror ( errno ) ) ;
}
return recv_len ;
}
/********************************************************************************************************************
name :
function :
return :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int tun_write_data ( int fd , char * send_buf , int send_buflen , struct stream_tuple4_v4 * ipv4_addr )
{
int succ_sendlen = 0 ;
succ_sendlen = write ( fd , send_buf , send_buflen ) ;
if ( succ_sendlen < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_WRITETUN , " write() error!msg is %s " , strerror ( errno ) ) ;
}
else if ( succ_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 ) )
{
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 " , 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 ;
}
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 ] ) ;
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 ;
}
long kni_readtun_htable_cb_v4 ( void * data , const unsigned char * key , unsigned int size , void * user_arg )
{
long result = 0 ;
struct datainfo_to_tun * ret_data = ( struct datainfo_to_tun * ) user_arg ;
struct datainfo_to_tun * datainfo = ( struct datainfo_to_tun * ) data ;
if ( datainfo ! = NULL )
{
ret_data - > route_dir = datainfo - > route_dir ;
ret_data - > mss = datainfo - > mss ;
ret_data - > state_flag = datainfo - > state_flag ;
memcpy ( ret_data - > smac , datainfo - > smac , MAC_ADDR_LEN ) ;
memcpy ( ret_data - > dmac , datainfo - > dmac , MAC_ADDR_LEN ) ;
result = 1 ;
}
return result ;
}
int kni_process_readdata ( int thread_seq , int buflen , char * buf )
{
2018-06-20 10:45:58 +08:00
// int ret=0;
2018-06-19 11:47:26 +08:00
int iprever_flag = 0 ;
2018-06-20 10:45:58 +08:00
// unsigned char routdir=0;
2018-06-19 11:47:26 +08:00
long result = 0 ;
struct datainfo_to_tun datainfo ;
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 ) ;
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 * ) & datainfo , & result ) ;
if ( result = = 1 )
{
if ( iprever_flag = = 1 )
{
2018-06-20 10:45:58 +08:00
// routdir=MESA_dir_reverse(datainfo.route_dir);
2018-06-19 11:47:26 +08:00
}
2018-06-20 10:45:58 +08:00
kni_sendpkt_eth ( thread_seq , buflen , buf , & ipv4_addr , iprever_flag , datainfo . smac , datainfo . dmac ) ;
2018-06-19 11:47:26 +08:00
}
}
else
{
iprever_flag = kni_get_ipaddr_v6 ( ( void * ) buf , & ipv6_addr ) ;
}
return 0 ;
}
/********************************************************************************************************************
name :
function :
return :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void * kni_read_tun ( void * arg )
{
int i = 0 ;
int recv_len = 0 ;
char recv_buf [ KNI_MAX_BUFLEN ] = { 0 } ;
while ( 1 )
{
for ( i = 0 ; 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 ;
st - > snd_wscale = 0 ;
st - > rcv_wscale = 0 ;
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 )
{
2018-06-20 10:45:58 +08:00
// int ret=0;
// int val = 1;
2018-06-19 11:47:26 +08:00
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 ) ;
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 ;
}
/***************************************************************************************
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 ;
}
unsigned short kni_get_mss ( struct kni_tcp_hdr * tcphdr , int tcp_hdr_len )
{
unsigned short mss = KNI_DEFAULT_MSS ;
return mss ;
int remain_len = tcp_hdr_len ;
struct kni_tcp_opt * tcp_opt = NULL ;
if ( ( tcp_hdr_len < = 20 ) | | ( tcp_hdr_len > 64 ) )
{
return mss ;
}
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
{
mss = * ( unsigned short * ) ( tcp_opt - > content ) ;
return mss ;
}
else if ( ( tcp_opt - > type = = 0 ) | | ( tcp_opt - > type = = 1 ) )
{
remain_len - = 1 ;
tcp_opt = ( struct kni_tcp_opt * ) ( ( char * ) tcp_opt + 1 ) ;
}
else
{
remain_len - = tcp_opt - > len ;
tcp_opt = ( struct kni_tcp_opt * ) ( ( char * ) tcp_opt + tcp_opt - > len ) ;
}
}
return mss ;
}
long kni_state_htable_cb_v4 ( void * data , const unsigned char * key , unsigned int size , void * user_arg )
{
2018-06-20 10:45:58 +08:00
// unsigned short mss=KNI_DEFAULT_MSS;
2018-06-19 11:47:26 +08:00
long state_flag = STAT_FLAG_NONE ;
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 ) ;
//first stream pkt and syn and not syn/ack
// 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 ) ) ;
datainfo - > route_dir = arg - > routdir ;
memset ( & addr_ipbmd , 0 , sizeof ( struct ipaddr ) ) ;
addr_ipbmd . addrtype = ADDR_TYPE_IPV4 ;
addr_ipbmd . v4 = ( struct stream_tuple4_v4 * ) key ;
datainfo - > state_flag = kni_judge_ipbmd ( & addr_ipbmd , arg - > thread_seq ) ;
datainfo - > mss = kni_get_mss ( tcphdr , ntohs ( iphdr - > ip_len ) - 4 * ( iphdr - > ip_hl ) - arg - > tcpdata_len ) ;
//for sendpkt test
if ( arg - > iprevers = = 0 )
{
memcpy ( datainfo - > smac , mac_addr - > src_mac , MAC_ADDR_LEN ) ;
memcpy ( datainfo - > dmac , mac_addr - > dst_mac , MAC_ADDR_LEN ) ;
}
else
{
memcpy ( datainfo - > smac , mac_addr - > dst_mac , MAC_ADDR_LEN ) ;
memcpy ( datainfo - > dmac , mac_addr - > src_mac , MAC_ADDR_LEN ) ;
}
//end
MESA_htable_add ( g_kni_structinfo . htable_to_tun_v4 , key , size , ( void * ) datainfo ) ;
}
if ( datainfo = = NULL )
{
return state_flag ;
}
/*
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 ;
}
*/
//only process full stream pkt,star from syn,double dir;
if ( ( datainfo - > state_flag = = STAT_FLAG_NONE ) & & ( arg - > tcpdata_len > 0 ) )
{
datainfo - > state_flag = kni_judge_ssl ( arg - > tcpdata , arg - > tcpdata_len , sni , & sni_len ) ;
if ( datainfo - > state_flag = = STAT_FLAG_SSL_NOBMD )
{
datainfo - > state_flag = kni_judge_sni ( sni , sni_len , arg - > thread_seq ) ;
if ( datainfo - > state_flag = = STAT_FLAG_SSL_NOBMD )
{
kni_process_fs ( arg - > a_packet , datainfo - > mss ) ;
}
}
}
return datainfo - > state_flag ; ;
}
long kni_state_htable_cb_v6 ( void * data , const unsigned char * key , unsigned int size , void * user_arg )
{
struct ipaddr addr_ipbmd ;
// struct stream_tuple4_v6* ipv4_addr=(struct stream_tuple4_v6*)key;
struct datainfo_to_tun * datainfo = ( struct datainfo_to_tun * ) data ;
struct args_to_tun * arg = ( struct args_to_tun * ) user_arg ;
if ( datainfo = = NULL )
{
datainfo = ( struct datainfo_to_tun * ) malloc ( sizeof ( struct datainfo_to_tun ) ) ;
memset ( datainfo , 0 , sizeof ( struct datainfo_to_tun ) ) ;
MESA_htable_add ( g_kni_structinfo . htable_to_tun_v4 , key , size , ( void * ) datainfo ) ;
memset ( & addr_ipbmd , 0 , sizeof ( struct ipaddr ) ) ;
addr_ipbmd . addrtype = ADDR_TYPE_IPV6 ;
addr_ipbmd . v4 = ( struct stream_tuple4_v4 * ) key ;
datainfo - > state_flag = kni_judge_ipbmd ( & addr_ipbmd , arg - > thread_seq ) ;
}
return datainfo - > state_flag ;
}
extern " C " int kni_ip_entry ( struct streaminfo * f_stream , unsigned char routedir , int thread_seq , struct ip * a_packet )
{
printf ( " kni_ip_entry! \n " ) ;
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 ) )
{
printf ( " kni_ip_entry return,ret:%d \n " , ret ) ;
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 ) ;
printf ( " kni_ip_entry return,ret:%d \n " , ret ) ;
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-06-20 10:45:58 +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 ;
}
//sendpkt init
// wangyan_send_fake_pkt_init();
//maat
g_kni_maatinfo . maat_feather = Maat_feather ( g_iThreadNum , table_info_path , g_kni_comminfo . logger ) ;
if ( g_kni_maatinfo . maat_feather = = NULL )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " Maat_feather() error!table_info_path:%s,action:%s " , table_info_path , KNI_ACTION_EXIT ) ;
return - 1 ;
}
if ( maat_json_switch = = 1 )
{
Maat_set_feather_opt ( g_kni_maatinfo . maat_feather , MAAT_OPT_JSON_FILE_PATH , KNI_MAATJSON_FILEPATH , strlen ( KNI_MAATJSON_FILEPATH ) ) ;
}
else
{
Maat_set_feather_opt ( g_kni_maatinfo . maat_feather , MAAT_OPT_FULL_CFG_DIR , full_cfg_dir , strlen ( full_cfg_dir ) ) ;
Maat_set_feather_opt ( g_kni_maatinfo . maat_feather , MAAT_OPT_INC_CFG_DIR , inc_cfg_dir , strlen ( inc_cfg_dir ) ) ;
}
ret = Maat_initiate_feather ( g_kni_maatinfo . maat_feather ) ;
if ( ret < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " Maat_initiate_feather() error!action:%s " , KNI_ACTION_EXIT ) ;
return - 1 ;
}
g_kni_maatinfo . tableid_ipbmd = Maat_table_register ( g_kni_maatinfo . maat_feather , KNI_TABLENAME_IPBMD ) ;
g_kni_maatinfo . tableid_snibmd = Maat_table_register ( g_kni_maatinfo . maat_feather , KNI_TABLENAME_SNIBMD ) ;
if ( ( g_kni_maatinfo . tableid_ipbmd < 0 ) | | ( g_kni_maatinfo . tableid_snibmd < 0 ) )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " Maat_table_register() error!ip_tableid:%d,sni_tableid:%d,action:%s " , g_kni_maatinfo . tableid_ipbmd , g_kni_maatinfo . tableid_snibmd , KNI_ACTION_EXIT ) ;
return - 1 ;
}
//init htable
ret = init_kni_stat_htable ( ) ;
if ( ret < 0 )
{
return - 1 ;
}
//init tun
if ( g_kni_comminfo . thread_num < = 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " thread_num:%d,action:%s " , g_kni_comminfo . thread_num , KNI_ACTION_EXIT ) ;
return - 1 ;
}
g_kni_comminfo . fd_tun = ( int * ) malloc ( g_kni_comminfo . thread_num * sizeof ( int ) ) ;
memset ( g_kni_comminfo . fd_tun , 0 , sizeof ( g_kni_comminfo . thread_num * sizeof ( int ) ) ) ;
ret = tun_alloc_mq ( __tun_symbol , g_kni_comminfo . thread_num , g_kni_comminfo . fd_tun ) ;
if ( ret < 0 )
{
return - 1 ;
}
system ( " ifconfig tun0 192.168.100.1 up " ) ;
system ( " route add default dev tun0 " ) ;
system ( " iptables -t mangle -A PREROUTING -p tcp -i tun0 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 50080 " ) ;
//init domain
g_kni_comminfo . fd_domain = init_domain_fd ( ) ;
if ( g_kni_comminfo . fd_domain < 0 )
{
MESA_handle_runtime_log ( g_kni_comminfo . logger , RLOG_LV_FATAL , KNI_MODULE_INIT , " init_domain_fd()error,action:%s " , KNI_ACTION_EXIT ) ;
return - 1 ;
}
//test init raw_socket
g_kni_comminfo . ipv4_fd = ( int * ) malloc ( g_kni_comminfo . thread_num * sizeof ( int ) ) ;
for ( i = 0 ; i < 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 ;
}
}
//init lqueue
/*
g_kni_structinfo . lqueue_to_tun = ( MESA_lqueue_head * ) malloc ( g_kni_comminfo . thread_num * sizeof ( MESA_lqueue_head ) ) ;
for ( i = 0 ; i < g_kni_comminfo . thread_num ; i + + )
{
g_kni_structinfo . lqueue_to_tun [ i ] = MESA_lqueue_create ( KNI_THREAD_SAFE , KNI_LQUEUE_MAXNUM ) ;
if ( g_kni_structinfo . lqueue_to_tun [ i ] = = NULL )
{
printf ( " MESA_lqueue_create() error! \n " ) ;
return - 1 ;
}
}
pthread_create ( & pid_write_tun , NULL , kni_write_tun , NULL ) ;
*/
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 ;
}