集成解密流量转发模块

This commit is contained in:
Lu Qiuwen
2018-09-02 16:34:15 +08:00
parent e1794342d5
commit 6bf1a5a9c8
14 changed files with 1666 additions and 2 deletions

View File

@@ -9,3 +9,4 @@ add_subdirectory(vendor)
add_subdirectory(common) add_subdirectory(common)
add_subdirectory(platform) add_subdirectory(platform)
add_subdirectory(cache) add_subdirectory(cache)
add_subdirectory(plugin)

View File

@@ -14,7 +14,6 @@ target_link_libraries(tfe pthread dl
MESA_handle_logger MESA_handle_logger
MESA_prof_load MESA_prof_load
MESA_htable wiredcfg MESA_htable wiredcfg
MESA_field_stat MESA_field_stat)
plugin_deliver)
install(TARGETS tfe RUNTIME DESTINATION ./) install(TARGETS tfe RUNTIME DESTINATION ./)

3
plugin/CMakeLists.txt Normal file
View File

@@ -0,0 +1,3 @@
add_subdirectory(protocol)
add_subdirectory(business)
add_subdirectory(platform)

View File

@@ -0,0 +1 @@
add_subdirectory(decrypt-mirroring)

View File

@@ -0,0 +1,5 @@
add_library(decrypt-mirroring src/deliver.cpp src/sendpkt.cpp)
target_include_directories(decrypt-mirroring PRIVATE include/internal)
target_include_directories(decrypt-mirroring PUBLIC include/external)
target_link_libraries(decrypt-mirroring common)

View File

@@ -0,0 +1,88 @@
#ifndef DELIVER_PROCESS_H
#define DELIVER_PROCESS_H
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DELIVER_DIR_C2S 0x01
#define DELIVER_DIR_S2C 0x02
struct deliver_addr_info
{
struct sockaddr client;
struct sockaddr server;
};
/**************************************************************************
Description:deliver read config from filepath to init;
Paraments:
thread_num:[IN],total process data thread num
filepath:[IN], conf file path,read use MESA_prof_load;
Return:
0:succes
<0:error
***************************************************************************/
int deliver_init(int thread_num,char* filepath);
/**************************************************************************
Description:call this function before send a new session data
Paraments:
thread_seq:[IN], thread seq
addr:[IN],addr of the session to be send
pme:[OUT],buffer alive in the session,deliver malloc and free *pme;
Return:
0:succes
<0:error
***************************************************************************/
int deliver_session_start(int thread_seq,struct deliver_addr_info* addr,void** pme);
/**************************************************************************
Description:call this function when send session data
Paraments:
cur_dir:[IN], direction of current data,definition in DELIVER_DIR_***
thread_seq:[IN],thread seq
buflen:[IN],buffer len,tcp payload len;
buf:[IN],data fo the session to be send,tcp payload
pme:[OUT]
Return:
0:succes
<0:error
***************************************************************************/
int deliver_session_data(int cur_dir,int thread_seq,int buflen,char*buf,void** pme);
/**************************************************************************
Description:call this function after send all of session data
Paraments:
thread_seq:[IN], thread seq
pme:[OUT]; free *pme when deliver_end()
Return:
0:succes
<0:error
***************************************************************************/
int deliver_session_end(int thread_seq,void** pme);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,125 @@
#ifndef DELIVER_PRIVATE_H
#define DELIVER_PRIVATE_H
#include <decrypt-mirroring.h>
#include <MESA/field_stat2.h>
#ifndef MAX_THREAD_NUM
#define MAX_THREAD_NUM 128
#endif
#define DELIVER_DEFAULT_MTU 1500
#define DELIVER_SENDPKT_BUFLEN 2048
//runtime log
#define DELIVER_MODULE_INIT "deliver_init"
#define DELIVER_MODULE_SENDPKT "deliver_sendpkt"
#define DELIVER_SENDPKT_START "sendpkt_start"
#define DELIVER_SENDPKT_DEBUG "sendpkt_debug"
#define DELIVER_RECVPKT_DEBUG "recvpkt_debug"
#define DELIVER_SENDPKT_END "sendpkt_end"
#define DELIVER_FLAG_SENDPKT 0
#define DELIVER_FLAG_RECVPKT 1
#define DELIVER_FLAG_ENT 2
//init profile info
#define DELIVER_CARDNAME_LEN 128
#define DELIVER_CONF_MAXLEN 1024
#define DELIVER_CONF_MODE "DELIVER"
#define DELIVER_RCV_MAC "reveiver_mac"
#define PROTO_TYPE_TCP 6
#define PROTO_TYPE_UDP 17
//lqueue info
#define DELIVER_THREAD_SAFE 1
#define DELIVER_USLEEP_TIME 10
#define DELIVER_LQUEUE_MAXNUM 100000
//send pkt
#define DELIVER_MACADDR_LEN 6
#define DELIVER_MACADDR_STR_LEN 18
#define DELIVER_ETHER_LEN 14
#define TCPHDR_DEFAULT_LEN 20
//fs2 info
#define FS2_COLUMN_NUM 5
#define FS2_APPNAME "DELIVER"
enum deliver_fs_colume
{
FS2_COLUME_RECVPKT=0,
FS2_COLUME_RECVBYTE,
FS2_COLUME_SENDPKT,
FS2_COLUME_SENDBYTE,
FS2_COLUME_ERROR,
};
struct deliver_fs2_info
{
screen_stat_handle_t handler;
int column_id[FS2_COLUMN_NUM];
unsigned long long column_value[MAX_THREAD_NUM][FS2_COLUMN_NUM];
};
struct deliver_comm_info
{
int threadnum;
void* logger;
};
struct deliver_pkt_info
{
int dir;
unsigned int seq; //host order
unsigned int ack; //host order
unsigned int len; //host order,tcp payload len
unsigned short ipid; //host order
unsigned short win; //host order
unsigned char flag;
unsigned char ttl;
};
struct deliver_session_info
{
int recv_pkt;
int send_pkt;
long long recv_byte;
long long send_byte;
};
struct deliver_pme_info
{
unsigned char dst_macaddr[DELIVER_MACADDR_LEN];
struct deliver_addr_info addr_info;
struct deliver_pkt_info pkt_info;
struct deliver_session_info session_info;
};
struct deliver_recver_info
{
unsigned char dst_macaddr[DELIVER_MACADDR_LEN];
};
struct deliver_sendpkt_info
{
int mtu;
int thread_num;
int receiver_num;
struct ifreq ifr;
int* send_socket;
char senddevice[DELIVER_CARDNAME_LEN];
unsigned char src_macaddr[DELIVER_MACADDR_LEN];
struct deliver_recver_info* receiver_info;
};
#endif

View File

@@ -0,0 +1,140 @@
#ifndef DELIVER_SENDPKT_H
#define DELIVER_SENDPKT_H
#include <arpa/inet.h>
#include <netinet/in.h>
#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif
#define ARPHRD_ETHER 1 /* ethernet hardware format */
#define SENDPACKET_ETH_H 0xe /* Etherner header: 14 bytes */
#define SENDPACKET_IP_H 0x14 /* IP header: 20 bytes */
#define SENDPACKET_TCP_H 0x14 /* TCP header: 20 bytes */
struct mesa_ethernet_hdr
{
unsigned char ether_dhost[ETHER_ADDR_LEN]; /* destination ethernet address */
unsigned char ether_shost[ETHER_ADDR_LEN]; /* source ethernet address */
unsigned short ether_type; /* packet type ID */
};
struct mesa_ip4_hdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t ip_hl:4, /* header length */
ip_v:4; /* version */
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t ip_v:4, /* version */
ip_hl:4; /* header length */
#else
#error "Please check <endian.h>"
#endif
u_int8_t ip_tos; /* type of service */
u_int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
u_int16_t ip_off;
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_int16_t ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
/*
* IPv6 packet header prototype, add by LiJia 2012-03-19.
*/
struct mesa_ip6_hdr
{
u_int8_t ip6_flags[4]; /* version, traffic-class, flow-label */
u_int16_t ip6_payload_len; /* payload length, not contain header */
u_int8_t ip6_nxt_hdr; /* next header, same as protocol in IPv4 */
u_int8_t ip6_hop; /* hop limit, same as TTL in IPv4 */
struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* dest address */
};
#ifndef TH_FIN
#define TH_FIN 0x01
#endif
#ifndef TH_SYN
#define TH_SYN 0x02
#endif
#ifndef TH_RST
#define TH_RST 0x04
#endif
#ifndef TH_PUSH
#define TH_PUSH 0x08
#endif
#ifndef TH_ACK
#define TH_ACK 0x10
#endif
#ifndef TH_URG
#define TH_URG 0x20
#endif
struct mesa_tcp_hdr
{
u_int16_t th_sport; /* source port */
u_int16_t th_dport; /* destination port */
u_int32_t th_seq; /* sequence number */
u_int32_t th_ack; /* acknowledgement number */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u_int8_t th_x2:4, /* (unused) */
th_off:4; /* data offset */
#elif __BYTE_ORDER == __BIG_ENDIAN
u_int8_t th_off:4, /* data offset */
th_x2:4; /* (unused) */
#else
#error "Please check <endian.h>"
#endif
u_int8_t th_flags; /* control flags */
u_int16_t th_win; /* window */
u_int16_t th_sum; /* checksum */
u_int16_t th_urp; /* urgent pointer */
};
/*
* UDP packet header prototype.
*/
struct mesa_udp_hdr
{
u_int16_t uh_sport; /* soure port */
u_int16_t uh_dport; /* destination port */
u_int16_t uh_ulen; /* length */
u_int16_t uh_sum; /* checksum */
};
unsigned int deliver_rand(void);
unsigned int deliver_rand_range(unsigned int start, unsigned int end);
int deliver_get_dev_mac(const char *device, unsigned char mac[6]);
int deliver_mac_pton(const char *str, int delim, char *mac);
int deliver_do_checksum(unsigned char *buf, int protocol, int len);
int deliver_build_ethernet(unsigned char *dst, unsigned char *src, unsigned short type,
const unsigned char *payload, int payload_s, unsigned char *buf);
int deliver_build_ethhdr(unsigned char *dst, unsigned char *src, unsigned short type,unsigned char *buf);
int deliver_build_ipv6(unsigned char traffic_class, unsigned int flow_lable,
unsigned short len, unsigned char next_header, unsigned char hop,
const struct in6_addr *src, const struct in6_addr *dst,
const char *payload, int payload_s, unsigned char *buf);
int deliver_build_ipv4(unsigned short carry_layer_len, unsigned char tos, unsigned short id,
unsigned short frag, unsigned char ttl, unsigned char prot, unsigned int src, unsigned int dst,
const char *payload,int payload_s, unsigned char *buf);
int deliver_build_tcp(unsigned short sp, unsigned short dp, unsigned int seq, unsigned int ack,
unsigned char th_flags, unsigned short win, unsigned short urg,
const char *payload, int payload_s, unsigned char *buf);
#endif

View File

@@ -0,0 +1,730 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/ether.h>
#include <netpacket/packet.h>
#include <pthread.h>
#include <MESA/MESA_prof_load.h>
#include <MESA/MESA_handle_logger.h>
#include <MESA/field_stat2.h>
#include <decrypt-mirroring.h>
#include <decrypt-mirroring-inl.h>
#include <sendpkt-inl.h>
int g_deliver_version_VERSION_20180718;
unsigned char* g_deliver_sendbuf[MAX_THREAD_NUM];
struct deliver_comm_info g_deliver_comminfo;
struct deliver_sendpkt_info g_deliver_sendinfo;
struct deliver_fs2_info g_deliver_fs2info;
const char *g_deliver_fs2_name[FS2_COLUMN_NUM] ={"RECV_PKTS","RECV_BYTES","SEND_PKTS","SEND_BYTES","ERROR_PKTS"};
int deliver_set_filestate2(int thread_seq,int colum_index,int value)
{
if(thread_seq>=g_deliver_comminfo.threadnum)
{
MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,"deliver_set_filestate2","thread_seq:%d,thread_num:%d",thread_seq,g_deliver_comminfo.threadnum);
}
g_deliver_fs2info.column_value[thread_seq][colum_index]+=value;
return 0;
}
int deliver_filestate2_init(char* filepath)
{
int i=0;
int trans_switch=0;
int value=1;
unsigned int fs2_sport;
char fs2_filename[DELIVER_CONF_MAXLEN]={0};
char fs2_sip[DELIVER_CONF_MAXLEN]={0};
MESA_load_profile_string_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_filename",fs2_filename,DELIVER_CONF_MAXLEN,(char*)"./log/deliver_fs2.log");
MESA_load_profile_string_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_sip",fs2_sip,DELIVER_CONF_MAXLEN,(char*)"192.168.11.241");
MESA_load_profile_uint_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_sport",(unsigned int*)&fs2_sport,8125);
MESA_load_profile_uint_def((char*)filepath,(char*)DELIVER_CONF_MODE,(char*)"filestat2_trans_switch",(unsigned int*)&trans_switch,0);
g_deliver_fs2info.handler=FS_create_handle();
FS_set_para(g_deliver_fs2info.handler, OUTPUT_DEVICE,fs2_filename, strlen(fs2_filename)+1);
FS_set_para(g_deliver_fs2info.handler, PRINT_MODE, &value, sizeof(value));
FS_set_para(g_deliver_fs2info.handler, STAT_CYCLE, &value, sizeof(value));
FS_set_para(g_deliver_fs2info.handler, CREATE_THREAD, &value, sizeof(value));
FS_set_para(g_deliver_fs2info.handler, APP_NAME, FS2_APPNAME, strlen(FS2_APPNAME)+1);
if(trans_switch==1)
{
FS_set_para(g_deliver_fs2info.handler, STATS_SERVER_IP, fs2_sip, strlen(fs2_sip)+1);
FS_set_para(g_deliver_fs2info.handler, STATS_SERVER_PORT,&fs2_sport,sizeof(int));
}
for(i=0;i<FS2_COLUMN_NUM;i++)
{
g_deliver_fs2info.column_id[i]=FS_register(g_deliver_fs2info.handler, FS_STYLE_FIELD, FS_CALC_CURRENT,g_deliver_fs2_name[i]);
}
FS_start(g_deliver_fs2info.handler);
return 0;
}
void* deliver_filestat2(void* arg)
{
int i=0;
int j=0;
char* filepath=(char*)arg;
unsigned long long column_value[FS2_COLUMN_NUM];
deliver_filestate2_init(filepath);
while(1)
{
for(i=0;i<FS2_COLUMN_NUM;i++)
{
column_value[i]=0;
for(j=0;j<g_deliver_comminfo.threadnum;j++)
{
column_value[i]+=g_deliver_fs2info.column_value[j][i];
}
FS_operate(g_deliver_fs2info.handler,g_deliver_fs2info.column_id[i], 0,FS_OP_SET,column_value[i]);
}
sleep(1);
}
return NULL;
}
int deliver_debug_log_v6(int level,char* module,struct deliver_pme_info* pmeinfo,int flag,int recv_len)
{
struct deliver_session_info* session_info=&(pmeinfo->session_info);
struct deliver_pkt_info* pkt_info=&(pmeinfo->pkt_info);
struct sockaddr_in6* client_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.client);
struct sockaddr_in6* server_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.server);
char saddr_v6[INET6_ADDRSTRLEN ]={0};
char daddr_v6[INET6_ADDRSTRLEN ]={0};
unsigned short sport=ntohs(client_addr->sin6_port);
unsigned short dport=ntohs(server_addr->sin6_port);
inet_ntop(AF_INET6, (void *)&(client_addr->sin6_addr), saddr_v6, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, (void *)&(server_addr->sin6_addr), daddr_v6, INET6_ADDRSTRLEN);
switch(flag)
{
case DELIVER_FLAG_SENDPKT:
MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,len:%d,dir:%d,seq:%u,ack:%u,ipid:%d,win:%d,flag:%d",
saddr_v6,sport,daddr_v6,dport,pkt_info->len,pkt_info->dir,
pkt_info->seq,pkt_info->ack,pkt_info->ipid,pkt_info->win,pkt_info->flag);
break;
case DELIVER_FLAG_RECVPKT:
MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,dir:%d,recv_len:%d",
saddr_v6,sport,daddr_v6,dport,pkt_info->dir,recv_len);
break;
case DELIVER_FLAG_ENT:
MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,recvpkt:%d,recvbyte:%lld,sendpkt:%d,sendbytes:%lld",
saddr_v6,sport,daddr_v6,dport,session_info->recv_pkt,session_info->recv_byte,
session_info->send_pkt,session_info->recv_byte);
break;
}
return 0;
}
int deliver_debug_log_v4(int level,char* module,struct deliver_pme_info* pmeinfo,int flag,int recv_len)
{
struct deliver_session_info* session_info=&(pmeinfo->session_info);
struct deliver_pkt_info* pkt_info=&(pmeinfo->pkt_info);
struct sockaddr_in* client_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.client);
struct sockaddr_in* server_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.server);
char saddr_v4[INET_ADDRSTRLEN]={0};
char daddr_v4[INET_ADDRSTRLEN]={0};
unsigned short sport=ntohs(client_addr->sin_port);
unsigned short dport=ntohs(server_addr->sin_port);
inet_ntop(AF_INET, (void *)&(client_addr->sin_addr.s_addr), saddr_v4, INET_ADDRSTRLEN);
inet_ntop(AF_INET, (void *)&(server_addr->sin_addr.s_addr), daddr_v4, INET_ADDRSTRLEN);
switch(flag)
{
case DELIVER_FLAG_SENDPKT:
MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,len:%d,dir:%d,seq:%u,ack:%u,ipid:%d,win:%d,flag:%d",
saddr_v4,sport,daddr_v4,dport,pkt_info->len,pkt_info->dir,
pkt_info->seq,pkt_info->ack,pkt_info->ipid,pkt_info->win,pkt_info->flag);
break;
case DELIVER_FLAG_RECVPKT:
MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,dir:%d,recv_len:%d",
saddr_v4,sport,daddr_v4,dport,pkt_info->dir,recv_len);
break;
case DELIVER_FLAG_ENT:
MESA_handle_runtime_log(g_deliver_comminfo.logger,level,module,"addr:%s,%d,%s,%d,recvpkt:%d,recvbyte:%lld,sendpkt:%d,sendbytes:%lld",
saddr_v4,sport,daddr_v4,dport,session_info->recv_pkt,session_info->recv_byte,
session_info->send_pkt,session_info->recv_byte);
break;
}
return 0;
}
int deliver_sendpkt_ether(int thread_seq,int buflen,unsigned char* buf,unsigned char* dmac)
{
int ret=0;
if(-1==ioctl(g_deliver_sendinfo.send_socket[thread_seq],SIOCGIFINDEX,&(g_deliver_sendinfo.ifr)))
{
MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_INIT,"get if index error:%d,%s,name:%d",errno,strerror(errno),g_deliver_sendinfo.senddevice);
return -1;
}
// struct sockaddr_ll addr={0};
struct sockaddr_ll addr;
addr.sll_family=AF_PACKET;
addr.sll_halen=ETHER_ADDR_LEN;
addr.sll_ifindex=g_deliver_sendinfo.ifr.ifr_ifindex;
addr.sll_protocol=htons(ETH_P_IP);
memcpy(addr.sll_addr,dmac,ETHER_ADDR_LEN);
if(ioctl(g_deliver_sendinfo.send_socket[thread_seq],SIOCGIFHWADDR,&(g_deliver_sendinfo.ifr))==-1)
{
return -1;
}
ret=sendto(g_deliver_sendinfo.send_socket[thread_seq],buf,buflen,0,(struct sockaddr*)&addr,sizeof(addr));
if(ret<0)
{
deliver_set_filestate2(thread_seq,FS2_COLUME_ERROR,1);
MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_SENDPKT,"sendto() error,errno:%d,msg:%s!",errno,strerror(errno));
return ret;
}
deliver_set_filestate2(thread_seq,FS2_COLUME_SENDPKT,1);
deliver_set_filestate2(thread_seq,FS2_COLUME_SENDBYTE,buflen-14-20-20);
return ret;
}
int deliver_init_pmeinfo(struct deliver_addr_info* addr,void** pme)
{
//TODO:choose dst mac
int i=deliver_rand()%(g_deliver_sendinfo.receiver_num);
struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)malloc(sizeof(struct deliver_pme_info));
memset(pmeinfo,0,sizeof(struct deliver_pme_info));
memcpy((void*)&pmeinfo->addr_info,(void*)addr,sizeof(struct deliver_addr_info));
memcpy(pmeinfo->dst_macaddr,g_deliver_sendinfo.receiver_info[i].dst_macaddr,DELIVER_MACADDR_LEN);
*pme=pmeinfo;
return 0;
}
int deliver_send_v6(int thread_seq,struct deliver_pme_info* pmeinfo,int payload_len,char* payload)
{
int offset = 0;
unsigned short eth_type=0x0800;
struct sockaddr_in6* client_addr=NULL;
struct sockaddr_in6* server_addr=NULL;
int cur_dir=pmeinfo->pkt_info.dir;
struct deliver_pkt_info* curpkt_info=&(pmeinfo->pkt_info);
if(cur_dir==DELIVER_DIR_C2S)
{
client_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.client);
server_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.server);
}
else
{
client_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.server);
server_addr=(struct sockaddr_in6*)&(pmeinfo->addr_info.client);
}
offset = sizeof(struct mesa_ethernet_hdr);
deliver_build_tcp(ntohs(client_addr->sin6_port), ntohs(server_addr->sin6_port),
curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0,
payload,payload_len,
g_deliver_sendbuf[thread_seq]+offset+sizeof(struct mesa_ip6_hdr));
deliver_build_ipv6(0, 0, payload_len + sizeof(struct mesa_tcp_hdr), IPPROTO_TCP, curpkt_info->ttl,
&(client_addr->sin6_addr),&(server_addr->sin6_addr),NULL, 0,
g_deliver_sendbuf[thread_seq]+offset);
deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len);
deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_IP, SENDPACKET_IP_H);
deliver_build_ethernet((unsigned char*)(pmeinfo->dst_macaddr),(unsigned char*)(g_deliver_sendinfo.src_macaddr),
eth_type,NULL,0,(unsigned char*)g_deliver_sendbuf[thread_seq]);
deliver_sendpkt_ether(thread_seq,SENDPACKET_TCP_H+SENDPACKET_IP_H+SENDPACKET_ETH_H+payload_len,
g_deliver_sendbuf[thread_seq],pmeinfo->dst_macaddr);
pmeinfo->session_info.send_pkt++;
pmeinfo->session_info.send_byte+=payload_len;
deliver_debug_log_v6(RLOG_LV_DEBUG,(char*)DELIVER_SENDPKT_DEBUG,pmeinfo,DELIVER_FLAG_SENDPKT,0);
return 0;
}
int deliver_send_v4(int thread_seq,struct deliver_pme_info* pmeinfo,int payload_len,char* payload)
{
int offset = 0;
unsigned short eth_type=0x0800;
struct sockaddr_in* client_addr=NULL;
struct sockaddr_in* server_addr=NULL;
int cur_dir=pmeinfo->pkt_info.dir;
struct deliver_pkt_info* curpkt_info=&(pmeinfo->pkt_info);
if(cur_dir==DELIVER_DIR_C2S)
{
client_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.client);
server_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.server);
}
else
{
client_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.server);
server_addr=(struct sockaddr_in*)&(pmeinfo->addr_info.client);
}
offset = sizeof(struct mesa_ethernet_hdr);
deliver_build_tcp(ntohs(client_addr->sin_port), ntohs(server_addr->sin_port),
curpkt_info->seq, curpkt_info->ack,curpkt_info->flag, curpkt_info->win, 0,
payload,payload_len,
g_deliver_sendbuf[thread_seq]+offset+sizeof(struct mesa_ip4_hdr));
deliver_build_ipv4(SENDPACKET_TCP_H+payload_len, 0, curpkt_info->ipid, 0, 64, IPPROTO_TCP,
client_addr->sin_addr.s_addr,server_addr->sin_addr.s_addr, NULL, 0,
g_deliver_sendbuf[thread_seq]+offset);
deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len);
deliver_do_checksum(g_deliver_sendbuf[thread_seq]+offset, IPPROTO_IP, SENDPACKET_IP_H);
deliver_build_ethernet((unsigned char*)(pmeinfo->dst_macaddr),(unsigned char*)(g_deliver_sendinfo.src_macaddr),
eth_type,NULL,0,(unsigned char*)g_deliver_sendbuf[thread_seq]);
deliver_sendpkt_ether(thread_seq,SENDPACKET_TCP_H+SENDPACKET_IP_H+SENDPACKET_ETH_H+payload_len,
g_deliver_sendbuf[thread_seq],pmeinfo->dst_macaddr);
pmeinfo->session_info.send_pkt++;
pmeinfo->session_info.send_byte+=payload_len;
deliver_debug_log_v4(RLOG_LV_DEBUG,(char*)DELIVER_SENDPKT_DEBUG,pmeinfo,DELIVER_FLAG_SENDPKT,0);
return 0;
}
int deliver_send_syn(int thread_seq,struct deliver_pme_info* pmeinfo)
{
pmeinfo->pkt_info.dir=DELIVER_DIR_C2S;
pmeinfo->pkt_info.len=0;
pmeinfo->pkt_info.seq= deliver_rand();
pmeinfo->pkt_info.ack=0;
pmeinfo->pkt_info.flag=TH_SYN;
pmeinfo->pkt_info.win = deliver_rand_range(1460, 65500);
pmeinfo->pkt_info.ipid = deliver_rand() % 65535;
pmeinfo->pkt_info.ttl=deliver_rand_range(32,65);
if(pmeinfo->addr_info.client.sa_family==AF_INET)
{
deliver_send_v4(thread_seq,pmeinfo,0,NULL);
deliver_debug_log_v4(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_START,pmeinfo,DELIVER_FLAG_SENDPKT,0);
}
else
{
deliver_send_v6(thread_seq,pmeinfo,0,NULL);
deliver_debug_log_v6(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_START,pmeinfo,DELIVER_FLAG_SENDPKT,0);
}
return 0;
}
int deliver_send_syn_ack(int thread_seq,struct deliver_pme_info* pmeinfo)
{
pmeinfo->pkt_info.dir=DELIVER_DIR_S2C;
pmeinfo->pkt_info.len=0;
pmeinfo->pkt_info.ack=pmeinfo->pkt_info.seq+1;
pmeinfo->pkt_info.seq= deliver_rand();
pmeinfo->pkt_info.flag=TH_SYN|TH_ACK;
if(pmeinfo->addr_info.client.sa_family==AF_INET)
{
deliver_send_v4(thread_seq,pmeinfo,0,NULL);
}
else
{
deliver_send_v6(thread_seq,pmeinfo,0,NULL);
}
return 0;
}
int deliver_send_ack(int thread_seq,struct deliver_pme_info* pmeinfo)
{
unsigned int ack_tmp=pmeinfo->pkt_info.ack;
pmeinfo->pkt_info.dir=DELIVER_DIR_C2S;
pmeinfo->pkt_info.len=0;
pmeinfo->pkt_info.ack=pmeinfo->pkt_info.seq+1;
pmeinfo->pkt_info.seq= ack_tmp;
pmeinfo->pkt_info.flag=TH_ACK;
if(pmeinfo->addr_info.client.sa_family==AF_INET)
{
deliver_send_v4(thread_seq,pmeinfo,0,NULL);
}
else
{
deliver_send_v6(thread_seq,pmeinfo,0,NULL);
}
return 0;
}
int deliver_set_pktinfo(struct deliver_pme_info* pmeinfo,int flag,int cur_dir,int payload_len)
{
struct deliver_pkt_info last_pkt_info;
memcpy((void*)&last_pkt_info,(void*)&(pmeinfo->pkt_info),sizeof(struct deliver_pkt_info));
pmeinfo->pkt_info.dir=cur_dir;
pmeinfo->pkt_info.len=payload_len;
pmeinfo->pkt_info.flag=flag;
if(cur_dir==last_pkt_info.dir)
{
pmeinfo->pkt_info.seq=last_pkt_info.seq+last_pkt_info.len;
pmeinfo->pkt_info.ack=last_pkt_info.ack;
}
else
{
pmeinfo->pkt_info.seq=last_pkt_info.ack;
pmeinfo->pkt_info.ack=last_pkt_info.seq+last_pkt_info.len;
}
return 0;
}
int deliver_send_rst(int thread_seq,struct deliver_pme_info* pmeinfo)
{
deliver_set_pktinfo(pmeinfo,TH_RST,DELIVER_DIR_C2S,0);
if(pmeinfo->addr_info.client.sa_family==AF_INET)
{
deliver_send_v4(thread_seq,pmeinfo,0,NULL);
}
else
{
deliver_send_v6(thread_seq,pmeinfo,0,NULL);
}
deliver_set_pktinfo(pmeinfo,TH_RST,DELIVER_DIR_S2C,0);
if(pmeinfo->addr_info.client.sa_family==AF_INET)
{
deliver_send_v4(thread_seq,pmeinfo,0,NULL);
deliver_debug_log_v4(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_END,pmeinfo,DELIVER_FLAG_ENT,0);
}
else
{
deliver_send_v6(thread_seq,pmeinfo,0,NULL);
deliver_debug_log_v6(RLOG_LV_INFO,(char*)DELIVER_SENDPKT_END,pmeinfo,DELIVER_FLAG_ENT,0);
}
return 0;
}
int deliver_session_start(int thread_seq,struct deliver_addr_info* addr,void** pme)
{
struct deliver_pme_info* pmeinfo=NULL;
deliver_init_pmeinfo(addr,pme);
pmeinfo=(struct deliver_pme_info*)*pme;
deliver_send_syn(thread_seq,pmeinfo);
deliver_send_syn_ack(thread_seq,pmeinfo);
deliver_send_ack(thread_seq,pmeinfo);
return 0;
}
int deliver_session_data(int cur_dir,int thread_seq,int buflen,char*buf,void** pme)
{
int i=0;
char* payload=buf;
int payload_len=0;
int remain_len=buflen;
int pkt_num=(buflen/(g_deliver_sendinfo.mtu))+1;
struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)*pme;
deliver_set_filestate2(thread_seq,FS2_COLUME_RECVPKT,1);
deliver_set_filestate2(thread_seq,FS2_COLUME_RECVBYTE,buflen);
pmeinfo->session_info.recv_pkt++;
pmeinfo->session_info.recv_byte+=buflen;
if(pmeinfo->addr_info.client.sa_family==AF_INET)
{
deliver_debug_log_v4(RLOG_LV_DEBUG,(char*)DELIVER_RECVPKT_DEBUG,pmeinfo,DELIVER_FLAG_RECVPKT,buflen);
}
else
{
deliver_debug_log_v6(RLOG_LV_DEBUG,(char*)DELIVER_RECVPKT_DEBUG,pmeinfo,DELIVER_FLAG_RECVPKT,buflen);
}
for(i=0;i<pkt_num;i++)
{
payload_len=remain_len<(g_deliver_sendinfo.mtu)?remain_len:(g_deliver_sendinfo.mtu);
payload=buf+(buflen-remain_len);
remain_len-=g_deliver_sendinfo.mtu;
deliver_set_pktinfo(pmeinfo,TH_ACK,cur_dir,payload_len);
if(pmeinfo->addr_info.client.sa_family==AF_INET)
{
deliver_send_v4(thread_seq,pmeinfo,payload_len,payload);
}
else
{
deliver_send_v6(thread_seq,pmeinfo,payload_len,payload);
}
}
return 0;
}
int deliver_session_end(int thread_seq,void** pme)
{
struct deliver_pme_info* pmeinfo=(struct deliver_pme_info*)*pme;
deliver_send_rst(thread_seq,pmeinfo);
if(*pme!=NULL)
{
free(*pme);
*pme=NULL;
}
return 0;
}
int deliver_device_init()
{
char* if_name=g_deliver_sendinfo.senddevice;
//init socket
size_t ifname_len=strlen(if_name);
if(ifname_len<sizeof(g_deliver_sendinfo.ifr.ifr_name))
{
memset(g_deliver_sendinfo.ifr.ifr_name,0,IFNAMSIZ);
memcpy(g_deliver_sendinfo.ifr.ifr_name,if_name,ifname_len);
}
else
{
MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_INIT,"interface name :%s is too long\n",if_name);
return -1;
}
deliver_get_dev_mac(g_deliver_sendinfo.senddevice,g_deliver_sendinfo.src_macaddr);
return 0;
}
int deliver_profile_init(char* filepath,int* logger_level,char* logger_filepath)
{
int i=1;
char mac_addr_str[DELIVER_MACADDR_STR_LEN];
char receiver_mac_name[DELIVER_CARDNAME_LEN]={0};
//runtime log
MESA_load_profile_int_def(filepath,(char*)DELIVER_CONF_MODE,(char*)"logger_level",logger_level,RLOG_LV_INFO);
MESA_load_profile_string_def(filepath,(char*)DELIVER_CONF_MODE,(char*)"logger_filepath",logger_filepath,DELIVER_CONF_MAXLEN,"./log/deliver.log");
//sendpkt info
MESA_load_profile_int_def(filepath,(char*)DELIVER_CONF_MODE,(char*)"mtu",&(g_deliver_sendinfo.mtu),DELIVER_DEFAULT_MTU);
MESA_load_profile_int_def(filepath,(char*)DELIVER_CONF_MODE,(char*)"receiver_num",&(g_deliver_sendinfo.receiver_num),1);
MESA_load_profile_string_nodef(filepath,(char*)DELIVER_CONF_MODE,(char*)"senddevice",g_deliver_sendinfo.senddevice,DELIVER_CARDNAME_LEN);
g_deliver_sendinfo.receiver_info=(struct deliver_recver_info*)malloc(g_deliver_sendinfo.receiver_num*sizeof(struct deliver_recver_info));
for(i=1;i<=g_deliver_sendinfo.receiver_num;i++)
{
memset(mac_addr_str,0,DELIVER_MACADDR_STR_LEN);
memset(receiver_mac_name,0,DELIVER_CARDNAME_LEN);
sprintf(receiver_mac_name,"%s%d",DELIVER_RCV_MAC,i);
MESA_load_profile_string_nodef(filepath,(char*)DELIVER_CONF_MODE,(char*)receiver_mac_name,(char*)mac_addr_str,DELIVER_MACADDR_STR_LEN);
if(deliver_mac_pton(mac_addr_str, ':', (char *)(g_deliver_sendinfo.receiver_info[i-1].dst_macaddr)) < 0)
{
printf("error, receiver %d mac:%s is not correct, for example:00:11:22:33:44:55\n", i,mac_addr_str);
return -1;
}
}
return 0;
}
int deliver_socket_error(int n)
{
for(int i=0;i<n;i++)
{
close(g_deliver_sendinfo.send_socket[i]);
g_deliver_sendinfo.send_socket[i]=0;
}
return 0;
}
int deliver_init_log()
{
int i=0;
int j=0;
char mac_str[DELIVER_MACADDR_STR_LEN]={0};
for(j = 0; j < 6; j++)
{
sprintf(mac_str+3*j, "%02x:", (unsigned char)g_deliver_sendinfo.src_macaddr[j]);
}
mac_str[DELIVER_MACADDR_STR_LEN]=0;
MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_INIT,"mtu:%d,receiver_num:%d,senddevice:%s,mac:%s",
g_deliver_sendinfo.mtu,g_deliver_sendinfo.receiver_num,g_deliver_sendinfo.senddevice,mac_str);
for(i=0;i<g_deliver_sendinfo.receiver_num;i++)
{
for(j = 0; j < 6; j++)
{
sprintf(mac_str+3*j, "%02x:", (unsigned char)g_deliver_sendinfo.receiver_info[i].dst_macaddr[j]);
}
mac_str[DELIVER_MACADDR_STR_LEN]=0;
MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_INIT,"reveiver_mac:%s",mac_str);
}
return 0;
}
int deliver_init(int thread_num,char* filepath)
{
int i=0;
int logger_level;
char logger_filepath[DELIVER_CONF_MAXLEN]={0};
pthread_t pid_deliver_filestat2;
g_deliver_comminfo.threadnum=thread_num;
//profile
deliver_profile_init(filepath,&logger_level,logger_filepath);
//init runtime log
g_deliver_comminfo.logger=MESA_create_runtime_log_handle(logger_filepath,logger_level);
if(g_deliver_comminfo.logger==NULL)
{
printf("MESA_create_runtime_log_handle() error!exit...\n");
return -1;
}
//socket init
g_deliver_sendinfo.thread_num=thread_num;
g_deliver_sendinfo.send_socket=(int*)malloc(g_deliver_sendinfo.thread_num*sizeof(int));
for(i=0;i<g_deliver_sendinfo.thread_num;i++)
{
g_deliver_sendbuf[i] = (unsigned char*)malloc(g_deliver_sendinfo.mtu);
g_deliver_sendinfo.send_socket[i]=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_IP));
if((g_deliver_sendinfo.send_socket[i]<0) ||(g_deliver_sendbuf[i]==NULL))
{
deliver_socket_error(i);
MESA_handle_runtime_log(g_deliver_comminfo.logger, RLOG_LV_FATAL,DELIVER_MODULE_INIT,"ipv4_raw_socket error,i:%d",i);
return -1;
}
}
pthread_create(&pid_deliver_filestat2,NULL,deliver_filestat2,(void*)filepath);
deliver_device_init();
deliver_init_log();
MESA_handle_runtime_log(g_deliver_comminfo.logger,RLOG_LV_FATAL,DELIVER_MODULE_INIT,"thread_num:%d,filepath:%s,deliver.so init sucess!",thread_num,filepath);
return 0;
}

View File

@@ -0,0 +1,467 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <unistd.h>
#include <net/if.h>
#include <sendpkt-inl.h>
static volatile uint64_t g_rand_seed = 0x013579ABCDEF;
#define SENDPACKET_CKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
unsigned int deliver_rand(void)
{
return g_rand_seed ^ (unsigned int)random();
}
unsigned int deliver_rand_range(unsigned int start, unsigned int end)
{
unsigned int rand_num = deliver_rand();
if(start > end)
{
return end + rand_num % (start - end + 1);
}
return start + rand_num % (end - start + 1);
}
/* ascii字符转16进制 */
char MESA_ascii_to_hex(char ascii)
{
char c = 0;
switch(ascii)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
c = ascii - 0x30;
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
c = 10 + ascii - 0x61;
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
c = 10 + ascii - 0x41;
break;
}
return c;
}
/* 2012-04-10 LiJia add, 获取网卡MAC地址
参数:
device: 网卡名称
mac: 存储MAC地址的数组,结果为网络序,
如网卡MAC地址为11:22:33:44:55:66,则mac[0]为0x11,mac[5]为0x66.
返回值:
0: 正常
-1:错误
*/
int deliver_get_dev_mac(const char *device, unsigned char mac[6])
{
struct ifreq ifr;
int fd;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
{
return -1;
}
memset(ifr.ifr_ifrn.ifrn_name, 0, sizeof(ifr.ifr_ifrn.ifrn_name));
strncpy(ifr.ifr_ifrn.ifrn_name, device, sizeof(ifr.ifr_ifrn.ifrn_name));
if(ioctl(fd, SIOCGIFHWADDR, &ifr) == -1)
{
printf("Cann't get hwaddr of %s:%s\n", device, strerror(errno));
goto err_exit;
}
if(ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
{
printf("'%s' is not ethernet interface!\n", device);
goto err_exit;
}
memcpy(mac, ifr.ifr_ifru.ifru_addr.sa_data, 6);
close(fd);
return 0;
err_exit:
close(fd);
return -1;
}
/* 2012-04-11 LiJia add,将MAC字符串形式转换为16进制MAC地址.
参数:
str: MAC地址字符串
delim: 字符串分隔符,常见为':', '-'等,如: xx:xx:xx:xx:xx:xx
如果字符串无分隔符delim设为-1.
mac: 存储MAC地址的数组(指针),结果为网络序,
如网卡MAC地址为11:22:33:44:55:66,则mac[0]为0x11,mac[5]为0x66.
返回值:
0: 正常
-1:错误
*/
int deliver_mac_pton(const char *str, int delim, char *mac)
{
#define MAC_STR_LEN_DELIM (17) /* length of "11:22:33:44:55:66" */
#define MAC_STR_LEN_NODELIM (12) /* length of "112233445566" */
const char *s = str;
int i;
/* 检查输入合法性 */
if(delim != -1)
{
if(strlen(str) != MAC_STR_LEN_DELIM)
{
printf("MAC string length error!\n");
return -1;
}
}
else
{
if(strlen(str) != MAC_STR_LEN_NODELIM)
{
printf("MAC string length error!\n");
return -1;
}
}
/* 检查输入合法性同时转换成16进制值 */
for(i = 0; i < 6; i++)
{
mac[i] = 0; /* 先清零,赋值语句都是或操作 */
if(isxdigit(*s)==0)
{
printf("MAC string type error!\n");
return -1;
}
mac[i] |= MESA_ascii_to_hex(*s) << 4;
s++;
if(isxdigit(*s)==0)
{
printf("MAC string type error!\n");
return -1;
}
mac[i] |= MESA_ascii_to_hex(*s);
s++;
if((delim != -1) && i<5 && (*s++ != (char)delim))
{
printf("MAC string type error!\n");
return -1;
}
}
return 0;
}
int sendpacket_in_cksum(unsigned short *addr, int len)
{
int sum;
int nleft;
unsigned short ans;
unsigned short *w;
sum = 0;
ans = 0;
nleft = len;
w = addr;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(char *)(&ans) = *(char *)w;
sum += ans;
}
return (sum);
}
int deliver_do_checksum(unsigned char *buf, int protocol, int len)
{
struct mesa_ip4_hdr *iph_p;
struct mesa_ip6_hdr *ip6h_p;
int ip_hl;
int sum;
int is_ipv6 = 0;
sum = 0;
iph_p = (struct mesa_ip4_hdr *)buf;
if(4 == iph_p->ip_v) /* IP版本号字段IPv4和IPv6格式是相同的 */
{
ip_hl = iph_p->ip_hl << 2;
ip6h_p = NULL;
}
else if(6 == iph_p->ip_v)
{
ip6h_p = (struct mesa_ip6_hdr *)buf;
iph_p = NULL;
ip_hl = sizeof(struct mesa_ip6_hdr);
is_ipv6 = 1;
}
else
{
return (-1);
}
switch (protocol)
{
case IPPROTO_TCP:
{
struct mesa_tcp_hdr *tcph_p = (struct mesa_tcp_hdr *)(buf + ip_hl);
tcph_p->th_sum = 0;
if(is_ipv6)
{
sum = sendpacket_in_cksum((unsigned short*)&ip6h_p->ip6_src, 32);
}
else
{
sum = sendpacket_in_cksum((unsigned short *)&iph_p->ip_src, 8);
}
sum += ntohs(IPPROTO_TCP + len);
sum += sendpacket_in_cksum((unsigned short *)tcph_p, len);
tcph_p->th_sum = SENDPACKET_CKSUM_CARRY(sum);
break;
}
case IPPROTO_UDP:
{
struct mesa_udp_hdr *udph_p =(struct mesa_udp_hdr *)(buf + ip_hl);
udph_p->uh_sum = 0;
if(is_ipv6)
{
sum = sendpacket_in_cksum((unsigned short*)&ip6h_p->ip6_src, 32);
}
else
{
sum = sendpacket_in_cksum((unsigned short*)&iph_p->ip_src, 8);
}
sum += ntohs(IPPROTO_UDP + len);
sum += sendpacket_in_cksum((unsigned short*)udph_p, len);
udph_p->uh_sum = SENDPACKET_CKSUM_CARRY(sum);
break;
}
case IPPROTO_IP:
{
iph_p->ip_sum = 0;
sum = sendpacket_in_cksum((unsigned short*)iph_p, len);
iph_p->ip_sum = SENDPACKET_CKSUM_CARRY(sum);
break;
}
default:
{
return (-1);
}
}
return (1);
}
/*
if playload2 is not NULL, it means that there is ip spice, it must be copied first, then
playload is copied
otherwise, only payload is copied and it includes ip header
*/
int deliver_build_ethhdr(unsigned char *dst, unsigned char *src, unsigned short type,unsigned char *buf)
{
struct mesa_ethernet_hdr eth_hdr;
if (!buf)
{
return (-1);
}
memcpy(eth_hdr.ether_dhost, dst, ETHER_ADDR_LEN); /* destination address */
memcpy(eth_hdr.ether_shost, src, ETHER_ADDR_LEN); /* source address */
eth_hdr.ether_type = htons(type); /* packet type */
memcpy(buf, &eth_hdr, sizeof(eth_hdr));
return (0);
}
/*
if playload2 is not NULL, it means that there is ip spice, it must be copied first, then
playload is copied
otherwise, only payload is copied and it includes ip header
*/
int deliver_build_ethernet(unsigned char *dst, unsigned char *src, unsigned short type,
const unsigned char *payload, int payload_s, unsigned char *buf)
{
struct mesa_ethernet_hdr eth_hdr;
if (!buf)
{
return (-1);
}
memcpy(eth_hdr.ether_dhost, dst, ETHER_ADDR_LEN); /* destination address */
memcpy(eth_hdr.ether_shost, src, ETHER_ADDR_LEN); /* source address */
eth_hdr.ether_type = htons(type); /* packet type */
if (payload && payload_s)
{
memcpy(buf + SENDPACKET_ETH_H, payload, payload_s);
}
memcpy(buf, &eth_hdr, sizeof(eth_hdr));
return (0);
}
int deliver_build_ipv6(unsigned char traffic_class, unsigned int flow_lable,
unsigned short len, unsigned char next_header, unsigned char hop,
const struct in6_addr *src, const struct in6_addr *dst,
const char *payload, int payload_s, unsigned char *buf)
{
struct mesa_ip6_hdr *ip6_h;
if(!buf){
return -1;
}
ip6_h = (struct mesa_ip6_hdr *)buf;
memset(ip6_h, 0, sizeof(struct mesa_ip6_hdr));
ip6_h->ip6_flags[0] = 0x60 | ((traffic_class & 0xF0) >> 4);
ip6_h->ip6_flags[1] = ((traffic_class & 0x0F) << 4) | ((flow_lable & 0xF0000) >> 16);
ip6_h->ip6_flags[2] = flow_lable & 0x0FF00 >> 8;
ip6_h->ip6_flags[3] = flow_lable & 0x000FF;
ip6_h->ip6_payload_len = htons(len);
ip6_h->ip6_nxt_hdr = next_header;
ip6_h->ip6_hop = hop;
memcpy(&ip6_h->ip6_src, src, sizeof(struct in6_addr));
memcpy(&ip6_h->ip6_dst, dst, sizeof(struct in6_addr));
if(payload && payload_s)
{
memcpy(buf + sizeof(struct mesa_ip6_hdr), payload, payload_s);
}
return 0;
}
int deliver_build_ipv4(unsigned short carry_layer_len, unsigned char tos, unsigned short id,
unsigned short frag, unsigned char ttl, unsigned char prot, unsigned int src, unsigned int dst,
const char *payload,int payload_s, unsigned char *buf)
{
struct mesa_ip4_hdr *ip_hdr;
if (!buf)
{
return (-1);
}
ip_hdr = (struct mesa_ip4_hdr *)buf;
ip_hdr->ip_v = 4; /* version 4 */
ip_hdr->ip_hl = 5; /* 20 byte header */
ip_hdr->ip_tos = tos; /* IP tos */
ip_hdr->ip_len = htons(SENDPACKET_IP_H + carry_layer_len); /* total length */
ip_hdr->ip_id = htons(id); /* IP ID */
ip_hdr->ip_off = htons(frag); /* fragmentation flags */
ip_hdr->ip_ttl = ttl; /* time to live */
ip_hdr->ip_p = prot; /* transport protocol */
ip_hdr->ip_sum = 0; /* do this later */
ip_hdr->ip_src.s_addr = src; /* 为什么地址用网络序? 历史遗留原因, 改动太多,只能这么继续了 */
ip_hdr->ip_dst.s_addr = dst; /* 为什么地址用网络序? 历史遗留原因, 改动太多,只能这么继续了 */
if (payload && payload_s)
{
memcpy(buf + SENDPACKET_IP_H, payload, payload_s);
}
return (0);
}
int deliver_build_tcp(unsigned short sp, unsigned short dp, unsigned int seq, unsigned int ack,
unsigned char th_flags, unsigned short win, unsigned short urg,
const char *payload, int payload_s, unsigned char *buf)
{
struct mesa_tcp_hdr *tcp_hdr;
if (!buf)
{
return (-1);
}
tcp_hdr = (struct mesa_tcp_hdr *)buf;
tcp_hdr->th_sport = htons(sp); /* source port */
tcp_hdr->th_dport = htons(dp); /* destination port */
tcp_hdr->th_seq = htonl(seq); /* sequence number */
tcp_hdr->th_ack = htonl(ack); /* acknowledgement number */
tcp_hdr->th_flags = th_flags; /* control flags */
tcp_hdr->th_x2 = 0; /* UNUSED */
tcp_hdr->th_off = 5; /* 20 byte header */
tcp_hdr->th_win = htons(win); /* window size */
tcp_hdr->th_sum = 0; /* checksum done in userland */
tcp_hdr->th_urp = urg; /* urgent pointer */
if (payload && payload_s)
{
// memcpy(buf + SENDPACKET_TCP_H, payload, payload_s);
memcpy(buf + sizeof(struct mesa_tcp_hdr), payload, payload_s);
}
return (0);
}

View File

@@ -0,0 +1,104 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include "stream.h"
#include "MESA_prof_load.h"
#include "MESA_handle_logger.h"
#include "deliver.h"
extern int g_iThreadNum;
extern "C" char deliver_tcp_entry(const struct streaminfo* pstream,void** pme,int thread_seq,const void* ip_hdr)
{
char ret=APP_STATE_DROPPKT;
struct deliver_addr_info addrinfo;
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
if(pstream->opstate==OP_STATE_PENDING)
{
client_addr.sin_family=AF_INET;
client_addr.sin_port=pstream->addr.ipv4->source;
client_addr.sin_addr.s_addr=pstream->addr.ipv4->saddr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=pstream->addr.ipv4->dest;
server_addr.sin_addr.s_addr=pstream->addr.ipv4->daddr;
memcpy(&addrinfo.client,&client_addr,sizeof(struct sockaddr));
memcpy(&addrinfo.server,&server_addr,sizeof(struct sockaddr));
deliver_session_start(thread_seq,&addrinfo,pme);
}
if(ip_hdr!=NULL)
{
deliver_session_data(pstream->curdir,thread_seq,pstream->ptcpdetail->datalen,(char*)pstream->ptcpdetail->pdata,pme);
}
if(pstream->opstate==OP_STATE_CLOSE)
{
deliver_session_end(thread_seq,pme);
}
return ret;
}
extern "C" char deliver_tcpall_entry(const struct streaminfo* pstream,void** pme,int thread_seq,const void* ip_hdr)
{
char ret=APP_STATE_DROPPKT;
struct deliver_addr_info addrinfo;
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
if(pstream->pktstate==OP_STATE_PENDING)
{
client_addr.sin_port=pstream->addr.ipv4->source;
client_addr.sin_addr.s_addr=pstream->addr.ipv4->saddr;
server_addr.sin_port=pstream->addr.ipv4->dest;
server_addr.sin_addr.s_addr=pstream->addr.ipv4->daddr;
memcpy(&addrinfo.client,&client_addr,sizeof(struct sockaddr));
memcpy(&addrinfo.server,&server_addr,sizeof(struct sockaddr));
deliver_session_start(thread_seq,&addrinfo,pme);
}
if(ip_hdr!=NULL)
{
deliver_session_data(pstream->curdir,thread_seq,pstream->ptcpdetail->datalen,(char*)pstream->ptcpdetail->pdata,pme);
}
if(pstream->opstate==OP_STATE_CLOSE)
{
deliver_session_end(thread_seq,pme);
}
return ret;
}
extern "C" char test_deliver_init()
{
int ret=0;
ret=deliver_init(g_iThreadNum,(char*)"./conf/deliver.conf");
if(ret<0)
{
printf("test deliver init error!\n");
return -1;
}
return 0;
}

View File

@@ -0,0 +1 @@

View File

View File