diff options
| author | dump2file <[email protected]> | 2018-12-16 17:40:56 +0600 |
|---|---|---|
| committer | dump2file <[email protected]> | 2018-12-16 17:40:56 +0600 |
| commit | 1dbd08480b502266b24f7487fe7cf7be25156812 (patch) | |
| tree | 5c79457cbfcd7e1cd9a496b2f403d7c00728bc81 | |
| parent | 84a6c6bec7a8f59071111976fdc7adbed7decef6 (diff) | |
1.cmakelist和makefile调整,marsio模式支持make和cmake两种编译模式(make iomode=marsio 或者 ./rmake)
2.marsio模式支持从驱动读取virtual_link_id和rehash_index,以及发包模式支持设置对应的两个选项
| -rw-r--r-- | CMakeLists.txt | 10 | ||||
| -rw-r--r-- | dealpkt/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | dealpkt/Makefile | 1 | ||||
| -rw-r--r-- | dealpkt/plug_support.c | 1775 | ||||
| -rw-r--r-- | include/stream_inc/stream_inject.h | 430 | ||||
| -rw-r--r-- | include/stream_inc/stream_rawpkt.h | 214 | ||||
| -rw-r--r-- | include/support/mrtunnat_for_view.h | 145 | ||||
| -rw-r--r-- | inner_plug/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | inner_plug/Makefile | 1 | ||||
| -rw-r--r-- | packet_io/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | packet_io/Makefile | 347 | ||||
| -rw-r--r-- | packet_io/sendpacket.c | 7048 | ||||
| -rw-r--r-- | rmake | 3 |
13 files changed, 5034 insertions, 4959 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b98ce9..b32e37f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ option(OPT_IOMODE_PPF "Capture network traffic with libppf" OFF) option(OPT_IOMODE_PFRING "Capture network traffic with PF-RING" OFF) option(OPT_IOMODE_DPDK "Capture network traffic with DPDK" OFF) option(OPT_IOMODE_PAG_N95 "Capture network traffic with N95" OFF) +option(OPT_IOMODE_MARSIO "Capture network traffic with MARSIO" ON) if(OPT_IOMODE_PCAP) set(CAPTURE_MODE "PCAP") @@ -37,6 +38,11 @@ if(OPT_IOMODE_PAG_N95) set(CAPTURE_MODE "PAG_N95") endif() +if(OPT_IOMODE_MARSIO) + set(CAPTURE_MODE "MARSIO") + set(MARSIO_SDK_PREFIX "/opt/mrzcpd/" CACHE STRING "MARSIO Prefix") +endif() + if(CAPTURE_MODE MATCHES "PCAP") set(CAPTURE_DEFINITIONS -DONLY_PCAP -DIOMODE_PCAP) endif() @@ -57,6 +63,10 @@ if(CAPTURE_MODE MATCHES "DPDK") set(CAPTURE_DEFINITIONS -DCAPTURE_MODE_DPDK) endif() +if(CAPTURE_MODE MATCHES "MARSIO") + set(CAPTURE_DEFINITIONS -DCAPTURE_MODE_MARSIO -DIOMODE_MARSIO) +endif() + # Memory Allocator option(OPT_USE_DICTATOR "Use Dictator2 memory allocator" OFF) option(OPT_USE_TXMEM "Use Dictator2 for TileGX memory allocator" OFF) diff --git a/dealpkt/CMakeLists.txt b/dealpkt/CMakeLists.txt index cf83ef9..51ef9f4 100644 --- a/dealpkt/CMakeLists.txt +++ b/dealpkt/CMakeLists.txt @@ -10,6 +10,10 @@ include_directories(${CMAKE_SOURCE_DIR}/include/stream_inc) include_directories(${CMAKE_SOURCE_DIR}/include/support) include_directories(${CMAKE_SOURCE_DIR}/dealpkt) +if(OPT_IOMODE_MARSIO) + include_directories(${MARSIO_SDK_PREFIX}/include) +endif() + add_definitions(-D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H) add_definitions(-DPLATFORM_NSDPF_PAPP=1) diff --git a/dealpkt/Makefile b/dealpkt/Makefile index d1ab041..be3d04c 100644 --- a/dealpkt/Makefile +++ b/dealpkt/Makefile @@ -22,6 +22,7 @@ H_DIR += -I../support/rbtree H_DIR += -I/usr/include/MESA/ H_DIR += -I/opt/MESA/include H_DIR += -I/opt/MESA/include/MESA +H_DIR += -I/opt/mrzcpd/include TARGET = libdealpkt.a diff --git a/dealpkt/plug_support.c b/dealpkt/plug_support.c index bee0138..7fa9428 100644 --- a/dealpkt/plug_support.c +++ b/dealpkt/plug_support.c @@ -1,876 +1,899 @@ -/*
- ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���,
- ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��,
-*/
-#include "stream_internal.h"
-#include "stream_manage.h"
-#include "sysinfo.h"
-#include "packet_io.h"
-#include "packet_io_internal.h"
-#include "project_requirement.h"
-#include "project_internal.h"
-#include "dictator.h"
-#include <MESA/MESA_handle_logger.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <assert.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <pthread.h>
-#include <sys/select.h>
-#include <linux/version.h>
-
-#if IOMODE_MARSIO
-#include "marsio.h"
-#include "mrtunnat.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int G_DICTATOR_SW = 1;
-extern int g_packet_io_thread_num;
-
-extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
-
-int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value)
-{
- int ret = 0;
- const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt;
-
- if(NULL == voidpkt || NULL == void_value){
- return -1;
- }
-
- if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ���� */
- return -1;
- }
-
- switch(type){
- case RAW_PKT_GET_DATA:
- {
- void **out_value = (void **)void_value;
- *out_value = (void *)rawpkt->raw_pkt_data;
- }
- break;
-
- case RAW_PKT_GET_RAW_PKT_TYPE:
- {
- enum addr_type_t *out_value = (enum addr_type_t *)void_value;
- *out_value = rawpkt->low_layer_type;
- }
- break;
-
- case RAW_PKT_GET_TOT_LEN:
- {
- int *out_value = (int *)void_value;
- *out_value = rawpkt->raw_pkt_len;
- }
- break;
-
- case RAW_PKT_GET_TIMESTAMP:
- {
- struct timeval *out_value =(struct timeval *)void_value;
- memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval));
- }
- break;
-
- case RAW_PKT_GET_THIS_LAYER_HDR:
- {
- void **out_value = (void **)void_value;
- const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr;
- *out_value = (void *)this_layer_hdr;
- }
- break;
-
- case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN:
- {
- int *out_value = (int *)void_value;
- *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr;
- }
- break;
-
-#if IOMODE_MARSIO
- case RAW_PKT_GET_GDEV_IP:
- {
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- break;
- }
- int *out_value = (int *)void_value;
- *out_value = mr_ctrlzone->g_device_in_addr;
- }
- break;
-
-
- case RAW_PKT_GET_VXLAN_ID:
- {
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- break;
- }
- int *out_value = (int *)void_value;
-//modify by liuy 20181205
-// *out_value = ntohl(mr_ctrlzone->g_device_vpn_id);
- *out_value = ntohl(mr_ctrlzone->g_device_linkpair);
-//end
- }
- break;
-
- case RAW_PKT_GET_VXLAN_SPORT:
- {
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- break;
- }
- short *out_value = (short *)void_value;
- *out_value = mr_ctrlzone->l4_src_port;
- }
- break;
-
- case RAW_PKT_GET_VXLAN_ENCAP_TYPE:
- {
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- break;
- }
- unsigned char *out_value = (unsigned char *)void_value;
- *out_value = mr_ctrlzone->__encap_type;
- }
- break;
-
- case RAW_PKT_GET_VXLAN_LINK_DIR:
- {
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- break;
- }
- unsigned char *out_value = (unsigned char *)void_value;
- *out_value = mr_ctrlzone->route_dir;
- }
- break;
-
- case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC:
- {
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- break;
- }
- memcpy(void_value, mr_ctrlzone->g_device_mac, 6);
- }
- break;
-
- case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC:
- {
- const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */
- if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */
- ret = -1;
- break;
- }
- memcpy(void_value, mr_ctrlzone->l_device_mac, 6);
- }
- break;
-#endif
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value)
-{
- int ret = -1;
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
-
- if(NULL == out_value){
- return -1;
- }
-
- if((RAW_PKT_GET_DATA == type)
- && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){
- const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream);
- if(NULL == list_tmp){
- ret = -1;
- }else{
- const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value;
- *out_list = list_tmp;
- ret = 1;
- }
- return ret;
- }
-
- return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value);
-}
-
-/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/
-const char *printaddr (const struct layer_addr *paddrinfo,int threadindex)
-{
- static char maxbuf[64+1][128];
- char *buf=maxbuf[threadindex];
- char ip_str[64];
- struct stream_tuple4_v4 *paddr;
- struct stream_tuple4_v6 *paddr6;
-
- if(NULL == paddrinfo){
- return NULL;
- }
-
- switch(paddrinfo->addrtype){
- case ADDR_TYPE_IPV4:
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,64);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
- //strcat (buf, int_ntoa (paddr->daddr));
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
- }
- break;
-
- case ADDR_TYPE_IPV6:
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
- }
- break;
-
- case __ADDR_TYPE_IP_PAIR_V4:
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,128);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- strcat (buf, ">");
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- }
- break;
-
- case __ADDR_TYPE_IP_PAIR_V6:
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- strcat (buf, ">");
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- }
- break;
-
- default:
- {
- return (const char *)"Not support layer type";
- }
- break;
- }
-
- return buf;
-}
-
-/*
- This is a reentrant version of printaddr(),
- Convert tuple4 to string store in out_buf.
- Format: 10.0.0.1, 1234->10.0.0.2,5678.
-*/
-const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len)
-{
-#define __MIN_ADDR_STR_LEN (20) /* ��С��ַ�ַ�������, ����:1.1.1.1.1>2.2.2.2.2 */
- char maxbuf[128];
- char *buf=maxbuf;
- char ip_str[64];
- int addr_str_len;
- struct stream_tuple4_v4 *paddr;
- struct stream_tuple4_v6 *paddr6;
-
- if((NULL == paddrinfo) || (NULL == out_buf)){
- return "invalid args";
- }
-
- if(paddrinfo->addrtype==ADDR_TYPE_IPV4)
- {
- paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr;
- memset(buf,0,128);
- //strcpy (buf, int_ntoa (paddr->saddr));
- inet_ntop(AF_INET, &paddr->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source));
- //strcat (buf, int_ntoa (paddr->daddr));
- inet_ntop(AF_INET, &paddr->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest));
- }
- //to addjust
- else if(paddrinfo->addrtype==ADDR_TYPE_IPV6)
- {
- paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr);
- memset(buf,0,128);
- inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64);
- strcpy (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source));
- inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64);
- strcat (buf, ip_str);
- sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest));
- }
- else
- {
- return (const char *)"Not support layer type";
- }
-
- addr_str_len = strlen(buf) + 1; /* add EOF */
- if(addr_str_len > out_buf_len){
- return (const char *)"buf len not enough";
- }
-
- memcpy(out_buf, buf, addr_str_len);
-
- return out_buf;
-}
-
-
-struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info)
-{
- void *addr_value;
- struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr));
- addr_value = malloc(stack_info->addrlen);
-
- memcpy(heap_addr, stack_info, sizeof(struct layer_addr));
- memcpy(addr_value, stack_info->paddr, stack_info->addrlen);
- heap_addr->paddr = addr_value;
-
- return heap_addr;
-}
-
-void layer_addr_free(struct layer_addr *paddrinfo)
-{
- free(paddrinfo->paddr);
- free(paddrinfo);
-}
-
-int get_thread_count(void)
-{
- return g_packet_io_thread_num;
-}
-
-
-int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len)
-{
- int ret = -1;
-
- if((NULL == opt_val) || (opt_val_len <= 0)){
- return -1;
- }
-
- switch((int)opt){
- case (int)MSO_MAX_UNORDER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- if(opt_val_len != sizeof(struct max_unorder_opt)){
- printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n");
- ret = -1;
- break;
- }
- struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val;
- ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val);
- }
- break;
-
- case (int)MSO_NEED_ACK:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char nack = *((unsigned char *)opt_val);
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->needackflag = nack;
- ret = 0;
- }
- break;
-
- case (int)MSO_TAKEOVER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- int takeover = *((int *)opt_val);
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->takeoverflag = takeover;
- ret = 0;
- }
- break;
-
- case (int)MSO_TIMEOUT:
- {
- if(sizeof(short) != opt_val_len){
- printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n");
- ret = -1;
- break;
- }
- unsigned short tmout = *((unsigned short *)opt_val);
- ret = stream_set_single_stream_timeout(pstream, tmout);
- }
- break;
-
- case (int)MSO_IGNORE_RST_FIN:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- printf("MESA_set_stream_opt() error: stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char igrstfin = *((unsigned char *)opt_val);
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- pdetail_pr->ignore_rst_fin = igrstfin;
- ret = 0;
- }
- break;
-
- default:
- printf("MESA_set_stream_opt() error: unsupport MESA_stream_opt type!\n");
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-
-static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len)
-{
- struct max_unorder_opt out_val;
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail;
- UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0;
-
- memset(&out_val, 0, sizeof(struct max_unorder_opt));
- if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){
- out_uorder_C2S = pdetail_pr->pserver->maxunorder;
- out_val.stream_dir |= DIR_C2S;
- }
-
- if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){
- out_uorder_S2C = pdetail_pr->pclient->maxunorder;
- out_val.stream_dir |= DIR_S2C;
- }
-
- out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C;
-
- memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt));
-
- *opt_val_len = sizeof(struct max_unorder_opt);
-
- return 0;
-}
-
-int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len)
-{
- int ret = 0;
-
- if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){
- return -1;
- }
-
- switch((int)opt){
- case (int)MSO_MAX_UNORDER:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n");
- ret = -1;
- break;
- }
- *opt_val_len = sizeof(struct max_unorder_opt);
- ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len);
- }
- break;
-
- case (int)MSO_NEED_ACK:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char *nack = (unsigned char *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *nack = pdetail_pr->needackflag;
- *opt_val_len = sizeof(char);
- }
- break;
-
- case (int)MSO_TAKEOVER:
- {
- if(*opt_val_len < (int)sizeof(int)){
- ret = -1;
- break;
- }
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- int *takeover = (int *)opt_val;
- struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail);
- *takeover = pdetail_pr->takeoverflag;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case (int)MSO_TIMEOUT:
- {
- if(sizeof(short) != *opt_val_len){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n");
- ret = -1;
- break;
- }
- unsigned short *tmout = (unsigned short *)opt_val;
- struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream;
- *tmout = pstream_pr->timeout;
- *opt_val_len = sizeof(short);
- }
- break;
-
- case (int)MSO_IGNORE_RST_FIN:
- {
- if(STREAM_TYPE_TCP != pstream->type){
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- ret = -1;
- break;
- }
- unsigned char *igrstfin = (unsigned char *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *igrstfin = pdetail_pr->ignore_rst_fin;
- }
- break;
-
- case MSO_TCP_CREATE_LINK_MODE:
- {
- struct tcpdetail_private *pdetail_pr;
- UCHAR *out_val = (UCHAR *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n");
- break;
- }
-
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *out_val = pdetail_pr->creat_mod;
- *opt_val_len = sizeof(char);
- }
- break;
-
- case MSO_TCP_ISN_C2S:
- {
- struct tcpdetail_private *pdetail_pr;
- UINT32 *out_val = (UINT32 *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
- break;
- }
-
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n");
- break;
- }
- if(0 == pdetail_pr->iserverseq){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN seq!\n");
- break;
- }
- *out_val = pdetail_pr->iserverseq - 1;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case MSO_TCP_ISN_S2C:
- {
- /* TODO: �����������ظ�, ���ϲ� */
- struct tcpdetail_private *pdetail_pr;
- UINT32 *out_val = (UINT32 *)opt_val;
- if(STREAM_TYPE_TCP != pstream->type){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n");
- break;
- }
- pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n");
- break;
- }
-
- if(0 == pdetail_pr->iclientseq){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN/ACK seq!\n");
- break;
- }
-
- *out_val = pdetail_pr->iclientseq - 1;
- *opt_val_len = sizeof(int);
- }
- break;
-
- case MSO_TCP_SYN_OPT:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- struct tcp_option **out_val = (struct tcp_option **)opt_val;
- if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){
- *out_val = pstream_pr->syn_opt_array;
- *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
- ret = 0;
- }else{
- ret = -1;
- }
- }
- break;
-
- case MSO_TCP_SYNACK_OPT:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- struct tcp_option **out_val = (struct tcp_option **)opt_val;
- if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){
- *out_val = pstream_pr->synack_opt_array;
- *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */
- ret = 0;
- }else{
- ret = -1;
- }
- }
- break;
-
- case MSO_STREAM_TUNNEL_TYPE:
- {
- const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream;
- unsigned short *out_val = (unsigned short *)opt_val;
- *out_val = pstream_pr->stream_low_layer_tunnel_type;
- ret = 0;
- }
- break;
-
- case MSO_STREAM_CLOSE_REASON:
- {
- if(pstream->opstate != OP_STATE_CLOSE){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error: stream %p has not closed!\n", pstream);
- break;
- }
- if(pstream->type != STREAM_TYPE_TCP){
- ret = -1;
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport stream type:%d!\n", pstream->type);
- break;
- }
- UCHAR *close_reason = (UCHAR *)opt_val;
- struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail);
- *close_reason = pdetail_pr->link_state;
- }
- break;
-
- default:
- sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n", opt);
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int is_proxy_stream(const struct streaminfo *pstream)
-{
- int ret = 0;
-
- switch(pstream->type){
- case STREAM_TYPE_SOCKS4:
- case STREAM_TYPE_SOCKS5:
- case STREAM_TYPE_HTTP_PROXY:
- case STREAM_TYPE_OPENVPN:
- ret = 1;
- break;
-
- default:
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-
-void bind_thread_to_cpuid(int thread_id)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
-#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 440)
- cpu_set_t cpuset;
- u_long core_id;
- int res;
- int tot_cpu_num = sysconf(_SC_NPROCESSORS_ONLN);
-
- /* Bind this thread to a specific core */
- if(tot_cpu_num > 1) {
- core_id = (thread_id + 1) % tot_cpu_num;
-
- CPU_ZERO(&cpuset);
- CPU_SET(core_id, &cpuset);
- res = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
- if (res != 0){
- fprintf(stderr, "Error while binding thread %d to core %ld: errno=%i\n",
- thread_id, core_id, res);
- }else{
- printf("[Info]Binding thread %d to core %ld success!\n", thread_id, core_id);
- }
- }
-#endif
-#endif
- return;
-}
-
-
-extern int project_req_terminal_tag_id;
-/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */
-const unsigned char *get_terminal_tag(struct streaminfo *stream)
-{
- unsigned char *terminal_tag;
-
- if(project_req_terminal_tag_id < 0){
- return NULL;
- }
-
- terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id);
-
- return (const unsigned char *)terminal_tag;
-}
-
-int number_is_2powerN(uint n)
-{
- if(n & (n-1)){
- return 0;
- }
-
- return 1;
-}
-
-
-
-void *dictator_malloc(int thread_seq,size_t size)
-{
- /*
- if(malloccount%100000==0)
- {
- printf("malloc=%d,free=%d\n",malloccount,freecount);
- }
- */
-
- if(G_DICTATOR_SW){
-#if USE_MEMPOOL
- return __dictator_malloc(thread_seq, size);
-#endif
- }
-
- return malloc(size);
-}
-void dictator_free(int thread_seq,void *pbuf)
-{
-#if USE_MEMPOOL
- if(G_DICTATOR_SW){
- __dictator_free(thread_seq, pbuf);
- }
- else
-#endif
- {
- free(pbuf);
- }
-}
-
-void *dictator_realloc(int thread_seq, void *ptr, size_t size)
-{
-#if USE_MEMPOOL
- if(G_DICTATOR_SW){
- return __dictator_realloc(thread_seq, ptr, size);
- }
-#endif
-
- return realloc(ptr, size);
-}
-
-/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */
-char biz_retval_to_platform(char biz_ret)
-{
- char plat_ret = 0;
-
- if(biz_ret & PROT_STATE_GIVEME){
- plat_ret |= APP_STATE_GIVEME;
- }
-
- if(biz_ret & PROT_STATE_DROPME){
- plat_ret |= APP_STATE_DROPME;
- }
-
- if(biz_ret & PROT_STATE_DROPPKT){
- plat_ret |= APP_STATE_DROPPKT;
- }
-
- return plat_ret;
-}
-
-/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */
-char plat_state_to_biz(char plat_state)
-{
- char biz_ret = SESSION_STATE_CLOSE;
-
- switch(plat_state){
- case OP_STATE_PENDING:
- biz_ret = SESSION_STATE_PENDING;
- break;
-
- case OP_STATE_DATA:
- biz_ret = SESSION_STATE_DATA;
- break;
-
- case OP_STATE_CLOSE:
- biz_ret = SESSION_STATE_CLOSE;
- break;
-
- default:
- break;
- }
-
- return biz_ret;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
+/* + ���ļ���ƽ̨������Ҫ�Ĺ��ܺͺ���, + ���ṩ������ҵ�����Ľӿ�, ��MESA_set_stream_opt, printaddr��, +*/ +#include "stream_internal.h" +#include "stream_manage.h" +#include "sysinfo.h" +#include "packet_io.h" +#include "packet_io_internal.h" +#include "project_requirement.h" +#include "project_internal.h" +#include "dictator.h" +#include <MESA/MESA_handle_logger.h> +#include <stdio.h> +#include <unistd.h> +#include <assert.h> +#include <string.h> +#include <arpa/inet.h> +#include <pthread.h> +#include <sys/select.h> +#include <linux/version.h> + +#if IOMODE_MARSIO +#include "marsio.h" +#include "mrtunnat.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int G_DICTATOR_SW = 1; +extern int g_packet_io_thread_num; + +extern const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream); + +int get_opt_from_rawpkt(const void *voidpkt, int type, void *void_value) +{ + int ret = 0; + const raw_pkt_t *rawpkt = (const raw_pkt_t *)voidpkt; + + if(NULL == voidpkt || NULL == void_value){ + return -1; + } + + if(RAW_PKT_MAGIC_NUM != rawpkt->magic_num){ /* ������Դ��pappƽ̨, ��֧�ִ���� */ + return -1; + } + + switch(type){ + case RAW_PKT_GET_DATA: + { + void **out_value = (void **)void_value; + *out_value = (void *)rawpkt->raw_pkt_data; + } + break; + + case RAW_PKT_GET_RAW_PKT_TYPE: + { + enum addr_type_t *out_value = (enum addr_type_t *)void_value; + *out_value = rawpkt->low_layer_type; + } + break; + + case RAW_PKT_GET_TOT_LEN: + { + int *out_value = (int *)void_value; + *out_value = rawpkt->raw_pkt_len; + } + break; + + case RAW_PKT_GET_TIMESTAMP: + { + struct timeval *out_value =(struct timeval *)void_value; + memcpy(out_value, &rawpkt->raw_pkt_ts, sizeof(struct timeval)); + } + break; + + case RAW_PKT_GET_THIS_LAYER_HDR: + { + void **out_value = (void **)void_value; + const char *this_layer_hdr = (const char *)rawpkt->raw_pkt_data + rawpkt->offset_to_raw_pkt_hdr; + *out_value = (void *)this_layer_hdr; + } + break; + + case RAW_PKT_GET_THIS_LAYER_REMAIN_LEN: + { + int *out_value = (int *)void_value; + *out_value = rawpkt->raw_pkt_len - rawpkt->offset_to_raw_pkt_hdr; + } + break; + +#if IOMODE_MARSIO + case RAW_PKT_GET_GDEV_IP: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + int *out_value = (int *)void_value; + *out_value = mr_ctrlzone->g_device_in_addr; + } + break; + + + case RAW_PKT_GET_VXLAN_ID: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + int *out_value = (int *)void_value; +//modify by liuy 20181205 +// *out_value = ntohl(mr_ctrlzone->g_device_vpn_id); + *out_value = ntohl(mr_ctrlzone->g_device_linkpair); +//end + } + break; + + case RAW_PKT_GET_VXLAN_SPORT: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + short *out_value = (short *)void_value; + *out_value = mr_ctrlzone->l4_src_port; + } + break; + + case RAW_PKT_GET_VXLAN_ENCAP_TYPE: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + unsigned char *out_value = (unsigned char *)void_value; + *out_value = mr_ctrlzone->__encap_type; + } + break; + + case RAW_PKT_GET_VXLAN_LINK_DIR: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + unsigned char *out_value = (unsigned char *)void_value; + *out_value = mr_ctrlzone->route_dir; + } + break; + + case RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + memcpy(void_value, mr_ctrlzone->g_device_mac, 6); + } + break; + + case RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->__encap_len <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + memcpy(void_value, mr_ctrlzone->l_device_mac, 6); + } + break; + + case RAW_PKT_GET_VIRTUAL_LINK_ID: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->virtual_link_id <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + unsigned long long *out_value = (unsigned long long *)void_value; + *out_value = mr_ctrlzone->virtual_link_id; + } + break; + case RAW_PKT_GET_REHASH_INDEX: + { + const struct mr_tunnat_ctrlzone *mr_ctrlzone = (const struct mr_tunnat_ctrlzone *)marsio_buff_ctrlzone((marsio_buff_t *)rawpkt->io_lib_pkt_reference, 0); /* index */ + if(mr_ctrlzone->rehash_index <= 0){/* ��vxlan��, �϶�û����Щѡ�� */ + ret = -1; + break; + } + unsigned long long *out_value = (unsigned long long *)void_value; + *out_value = mr_ctrlzone->rehash_index; + } + break; +#endif + default: + ret = -1; + break; + } + + return ret; +} + +int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value) +{ + int ret = -1; + const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; + + if(NULL == out_value){ + return -1; + } + + if((RAW_PKT_GET_DATA == type) + && ((PKT_TYPE_IPREBUILD & pstream->addr.pktipfragtype) != 0)){ + const raw_ipfrag_list_t *list_tmp = get_raw_frag_list(pstream); + if(NULL == list_tmp){ + ret = -1; + }else{ + const raw_ipfrag_list_t **out_list = (const raw_ipfrag_list_t **)out_value; + *out_list = list_tmp; + ret = 1; + } + return ret; + } + + return get_opt_from_rawpkt(pstream_pr->raw_pkt, type, out_value); +} + +/*Convert tuple4 to string. Format: 10.0.0.1, 1234->10.0.0.2,5678*/ +const char *printaddr (const struct layer_addr *paddrinfo,int threadindex) +{ + static char maxbuf[64+1][128]; + char *buf=maxbuf[threadindex]; + char ip_str[64]; + struct stream_tuple4_v4 *paddr; + struct stream_tuple4_v6 *paddr6; + + if(NULL == paddrinfo){ + return NULL; + } + + switch(paddrinfo->addrtype){ + case ADDR_TYPE_IPV4: + { + paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr; + memset(buf,0,64); + //strcpy (buf, int_ntoa (paddr->saddr)); + inet_ntop(AF_INET, &paddr->saddr, ip_str, 64); + strcpy (buf, ip_str); + sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source)); + //strcat (buf, int_ntoa (paddr->daddr)); + inet_ntop(AF_INET, &paddr->daddr, ip_str, 64); + strcat (buf, ip_str); + sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest)); + } + break; + + case ADDR_TYPE_IPV6: + { + paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr); + memset(buf,0,128); + inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64); + strcpy (buf, ip_str); + sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source)); + inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64); + strcat (buf, ip_str); + sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest)); + } + break; + + case __ADDR_TYPE_IP_PAIR_V4: + { + paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr; + memset(buf,0,128); + //strcpy (buf, int_ntoa (paddr->saddr)); + inet_ntop(AF_INET, &paddr->saddr, ip_str, 64); + strcpy (buf, ip_str); + strcat (buf, ">"); + inet_ntop(AF_INET, &paddr->daddr, ip_str, 64); + strcat (buf, ip_str); + } + break; + + case __ADDR_TYPE_IP_PAIR_V6: + { + paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr); + memset(buf,0,128); + inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64); + strcpy (buf, ip_str); + strcat (buf, ">"); + inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64); + strcat (buf, ip_str); + } + break; + + default: + { + return (const char *)"Not support layer type"; + } + break; + } + + return buf; +} + +/* + This is a reentrant version of printaddr(), + Convert tuple4 to string store in out_buf. + Format: 10.0.0.1, 1234->10.0.0.2,5678. +*/ +const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len) +{ +#define __MIN_ADDR_STR_LEN (20) /* ��С��ַ�ַ�������, ����:1.1.1.1.1>2.2.2.2.2 */ + char maxbuf[128]; + char *buf=maxbuf; + char ip_str[64]; + int addr_str_len; + struct stream_tuple4_v4 *paddr; + struct stream_tuple4_v6 *paddr6; + + if((NULL == paddrinfo) || (NULL == out_buf)){ + return "invalid args"; + } + + if(paddrinfo->addrtype==ADDR_TYPE_IPV4) + { + paddr=(struct stream_tuple4_v4 *)paddrinfo->paddr; + memset(buf,0,128); + //strcpy (buf, int_ntoa (paddr->saddr)); + inet_ntop(AF_INET, &paddr->saddr, ip_str, 64); + strcpy (buf, ip_str); + sprintf (buf + strlen (buf), ".%u>", ntohs(paddr->source)); + //strcat (buf, int_ntoa (paddr->daddr)); + inet_ntop(AF_INET, &paddr->daddr, ip_str, 64); + strcat (buf, ip_str); + sprintf (buf + strlen (buf), ".%u", ntohs(paddr->dest)); + } + //to addjust + else if(paddrinfo->addrtype==ADDR_TYPE_IPV6) + { + paddr6=(struct stream_tuple4_v6 *)(paddrinfo->paddr); + memset(buf,0,128); + inet_ntop(AF_INET6, paddr6->saddr, ip_str, 64); + strcpy (buf, ip_str); + sprintf (buf + strlen (buf), ".%u>", ntohs(paddr6->source)); + inet_ntop(AF_INET6, paddr6->daddr, ip_str, 64); + strcat (buf, ip_str); + sprintf (buf + strlen (buf), ".%u", ntohs(paddr6->dest)); + } + else + { + return (const char *)"Not support layer type"; + } + + addr_str_len = strlen(buf) + 1; /* add EOF */ + if(addr_str_len > out_buf_len){ + return (const char *)"buf len not enough"; + } + + memcpy(out_buf, buf, addr_str_len); + + return out_buf; +} + + +struct layer_addr * layer_addr_dup(const struct layer_addr *stack_info) +{ + void *addr_value; + struct layer_addr *heap_addr = (struct layer_addr *)malloc(sizeof(struct layer_addr)); + addr_value = malloc(stack_info->addrlen); + + memcpy(heap_addr, stack_info, sizeof(struct layer_addr)); + memcpy(addr_value, stack_info->paddr, stack_info->addrlen); + heap_addr->paddr = addr_value; + + return heap_addr; +} + +void layer_addr_free(struct layer_addr *paddrinfo) +{ + free(paddrinfo->paddr); + free(paddrinfo); +} + +int get_thread_count(void) +{ + return g_packet_io_thread_num; +} + + +int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len) +{ + int ret = -1; + + if((NULL == opt_val) || (opt_val_len <= 0)){ + return -1; + } + + switch((int)opt){ + case (int)MSO_MAX_UNORDER: + { + if(STREAM_TYPE_TCP != pstream->type){ + printf("MESA_set_stream_opt() error:stream type is not tcp!\n"); + ret = -1; + break; + } + if(opt_val_len != sizeof(struct max_unorder_opt)){ + printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n"); + ret = -1; + break; + } + struct max_unorder_opt *max_uorder = (struct max_unorder_opt *)opt_val; + ret = tcp_set_single_stream_max_unorder(pstream, max_uorder->stream_dir, max_uorder->max_unorder_val); + } + break; + + case (int)MSO_NEED_ACK: + { + if(STREAM_TYPE_TCP != pstream->type){ + printf("MESA_set_stream_opt() error:stream type is not tcp!\n"); + ret = -1; + break; + } + unsigned char nack = *((unsigned char *)opt_val); + struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + pdetail_pr->needackflag = nack; + ret = 0; + } + break; + + case (int)MSO_TAKEOVER: + { + if(STREAM_TYPE_TCP != pstream->type){ + printf("MESA_set_stream_opt() error:stream type is not tcp!\n"); + ret = -1; + break; + } + int takeover = *((int *)opt_val); + struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail); + pdetail_pr->takeoverflag = takeover; + ret = 0; + } + break; + + case (int)MSO_TIMEOUT: + { + if(sizeof(short) != opt_val_len){ + printf("MESA_set_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n"); + ret = -1; + break; + } + unsigned short tmout = *((unsigned short *)opt_val); + ret = stream_set_single_stream_timeout(pstream, tmout); + } + break; + + case (int)MSO_IGNORE_RST_FIN: + { + if(STREAM_TYPE_TCP != pstream->type){ + printf("MESA_set_stream_opt() error: stream type is not tcp!\n"); + ret = -1; + break; + } + unsigned char igrstfin = *((unsigned char *)opt_val); + struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + pdetail_pr->ignore_rst_fin = igrstfin; + ret = 0; + } + break; + + default: + printf("MESA_set_stream_opt() error: unsupport MESA_stream_opt type!\n"); + ret = -1; + break; + } + + return ret; +} + + +static inline int tcp_get_single_stream_max_unorder(const struct streaminfo *pstream, void *opt_val, int *opt_val_len) +{ + struct max_unorder_opt out_val; + struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private *)pstream->pdetail; + UINT16 out_uorder_C2S = 0, out_uorder_S2C = 0; + + memset(&out_val, 0, sizeof(struct max_unorder_opt)); + if((pdetail_pr->pserver != NULL) && (tcp_default_unorder != pdetail_pr->pserver->maxunorder)){ + out_uorder_C2S = pdetail_pr->pserver->maxunorder; + out_val.stream_dir |= DIR_C2S; + } + + if((pdetail_pr->pclient != NULL) && (tcp_default_unorder != pdetail_pr->pclient->maxunorder)){ + out_uorder_S2C = pdetail_pr->pclient->maxunorder; + out_val.stream_dir |= DIR_S2C; + } + + out_val.max_unorder_val = (out_uorder_C2S > out_uorder_S2C)?out_uorder_C2S: out_uorder_S2C; + + memcpy(opt_val, &out_val, sizeof(struct max_unorder_opt)); + + *opt_val_len = sizeof(struct max_unorder_opt); + + return 0; +} + +int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len) +{ + int ret = 0; + + if((NULL == opt_val) || (NULL == opt_val_len) || (*opt_val_len <= 0)){ + return -1; + } + + switch((int)opt){ + case (int)MSO_MAX_UNORDER: + { + if(STREAM_TYPE_TCP != pstream->type){ + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n"); + ret = -1; + break; + } + if(*opt_val_len < (int)sizeof(struct max_unorder_opt)){ + sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(struct max_unorder_opt)\n"); + ret = -1; + break; + } + *opt_val_len = sizeof(struct max_unorder_opt); + ret = tcp_get_single_stream_max_unorder(pstream, opt_val, opt_val_len); + } + break; + + case (int)MSO_NEED_ACK: + { + if(STREAM_TYPE_TCP != pstream->type){ + sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n"); + ret = -1; + break; + } + unsigned char *nack = (unsigned char *)opt_val; + struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + *nack = pdetail_pr->needackflag; + *opt_val_len = sizeof(char); + } + break; + + case (int)MSO_TAKEOVER: + { + if(*opt_val_len < (int)sizeof(int)){ + ret = -1; + break; + } + if(STREAM_TYPE_TCP != pstream->type){ + sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n"); + ret = -1; + break; + } + int *takeover = (int *)opt_val; + struct tcpdetail_private *pdetail_pr=(struct tcpdetail_private*)(pstream->pdetail); + *takeover = pdetail_pr->takeoverflag; + *opt_val_len = sizeof(int); + } + break; + + case (int)MSO_TIMEOUT: + { + if(sizeof(short) != *opt_val_len){ + sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:opt_val_len invalid, must be sizeof(short)\n"); + ret = -1; + break; + } + unsigned short *tmout = (unsigned short *)opt_val; + struct streaminfo_private *pstream_pr=(struct streaminfo_private *)pstream; + *tmout = pstream_pr->timeout; + *opt_val_len = sizeof(short); + } + break; + + case (int)MSO_IGNORE_RST_FIN: + { + if(STREAM_TYPE_TCP != pstream->type){ + sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n"); + ret = -1; + break; + } + unsigned char *igrstfin = (unsigned char *)opt_val; + struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + *igrstfin = pdetail_pr->ignore_rst_fin; + } + break; + + case MSO_TCP_CREATE_LINK_MODE: + { + struct tcpdetail_private *pdetail_pr; + UCHAR *out_val = (UCHAR *)opt_val; + if(STREAM_TYPE_TCP != pstream->type){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG,"MESA_get_stream_opt() error:stream type is not tcp!\n"); + break; + } + + pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + *out_val = pdetail_pr->creat_mod; + *opt_val_len = sizeof(char); + } + break; + + case MSO_TCP_ISN_C2S: + { + struct tcpdetail_private *pdetail_pr; + UINT32 *out_val = (UINT32 *)opt_val; + if(STREAM_TYPE_TCP != pstream->type){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n"); + break; + } + + pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n"); + break; + } + if(0 == pdetail_pr->iserverseq){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN seq!\n"); + break; + } + *out_val = pdetail_pr->iserverseq - 1; + *opt_val_len = sizeof(int); + } + break; + + case MSO_TCP_ISN_S2C: + { + /* TODO: �����������ظ�, ���ϲ� */ + struct tcpdetail_private *pdetail_pr; + UINT32 *out_val = (UINT32 *)opt_val; + if(STREAM_TYPE_TCP != pstream->type){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:stream type is not tcp!\n"); + break; + } + pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + if(pdetail_pr->creat_mod != TCP_CTEAT_LINK_BYSYN){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: stream create mode is not by SYN!\n"); + break; + } + + if(0 == pdetail_pr->iclientseq){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error: can't get SYN/ACK seq!\n"); + break; + } + + *out_val = pdetail_pr->iclientseq - 1; + *opt_val_len = sizeof(int); + } + break; + + case MSO_TCP_SYN_OPT: + { + const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; + struct tcp_option **out_val = (struct tcp_option **)opt_val; + if((pstream_pr->syn_opt_array != NULL) && (pstream_pr->syn_opt_num > 0)){ + *out_val = pstream_pr->syn_opt_array; + *opt_val_len = pstream_pr->syn_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */ + ret = 0; + }else{ + ret = -1; + } + } + break; + + case MSO_TCP_SYNACK_OPT: + { + const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; + struct tcp_option **out_val = (struct tcp_option **)opt_val; + if((pstream_pr->synack_opt_array != NULL) && (pstream_pr->synack_opt_num > 0)){ + *out_val = pstream_pr->synack_opt_array; + *opt_val_len = pstream_pr->synack_opt_num; /* �˴����dz���, ��ʾopt_array�ĸ��� */ + ret = 0; + }else{ + ret = -1; + } + } + break; + + case MSO_STREAM_TUNNEL_TYPE: + { + const struct streaminfo_private *pstream_pr = (const struct streaminfo_private *)pstream; + unsigned short *out_val = (unsigned short *)opt_val; + *out_val = pstream_pr->stream_low_layer_tunnel_type; + ret = 0; + } + break; + + case MSO_STREAM_CLOSE_REASON: + { + if(pstream->opstate != OP_STATE_CLOSE){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() MSO_STREAM_CLOSE_REASON error: stream %p has not closed!\n", pstream); + break; + } + if(pstream->type != STREAM_TYPE_TCP){ + ret = -1; + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport stream type:%d!\n", pstream->type); + break; + } + UCHAR *close_reason = (UCHAR *)opt_val; + struct tcpdetail_private *pdetail_pr = (struct tcpdetail_private*)(pstream->pdetail); + *close_reason = pdetail_pr->link_state; + } + break; + + default: + sapp_runtime_log(RLOG_LV_DEBUG, "MESA_get_stream_opt() error:unsupport MESA_stream_opt type:%d!\n", opt); + ret = -1; + break; + } + + return ret; +} + +int is_proxy_stream(const struct streaminfo *pstream) +{ + int ret = 0; + + switch(pstream->type){ + case STREAM_TYPE_SOCKS4: + case STREAM_TYPE_SOCKS5: + case STREAM_TYPE_HTTP_PROXY: + case STREAM_TYPE_OPENVPN: + ret = 1; + break; + + default: + ret = 0; + break; + } + + return ret; +} + + +void bind_thread_to_cpuid(int thread_id) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 440) + cpu_set_t cpuset; + u_long core_id; + int res; + int tot_cpu_num = sysconf(_SC_NPROCESSORS_ONLN); + + /* Bind this thread to a specific core */ + if(tot_cpu_num > 1) { + core_id = (thread_id + 1) % tot_cpu_num; + + CPU_ZERO(&cpuset); + CPU_SET(core_id, &cpuset); + res = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (res != 0){ + fprintf(stderr, "Error while binding thread %d to core %ld: errno=%i\n", + thread_id, core_id, res); + }else{ + printf("[Info]Binding thread %d to core %ld success!\n", thread_id, core_id); + } + } +#endif +#endif + return; +} + + +extern int project_req_terminal_tag_id; +/* For863, ����Ӧ�ò�����ȡ��TCP���ж�Ӧ���û���ǩ */ +const unsigned char *get_terminal_tag(struct streaminfo *stream) +{ + unsigned char *terminal_tag; + + if(project_req_terminal_tag_id < 0){ + return NULL; + } + + terminal_tag = (unsigned char *)project_req_get_struct(stream, project_req_terminal_tag_id); + + return (const unsigned char *)terminal_tag; +} + +int number_is_2powerN(uint n) +{ + if(n & (n-1)){ + return 0; + } + + return 1; +} + + + +void *dictator_malloc(int thread_seq,size_t size) +{ + /* + if(malloccount%100000==0) + { + printf("malloc=%d,free=%d\n",malloccount,freecount); + } + */ + + if(G_DICTATOR_SW){ +#if USE_MEMPOOL + return __dictator_malloc(thread_seq, size); +#endif + } + + return malloc(size); +} +void dictator_free(int thread_seq,void *pbuf) +{ +#if USE_MEMPOOL + if(G_DICTATOR_SW){ + __dictator_free(thread_seq, pbuf); + } + else +#endif + { + free(pbuf); + } +} + +void *dictator_realloc(int thread_seq, void *ptr, size_t size) +{ +#if USE_MEMPOOL + if(G_DICTATOR_SW){ + return __dictator_realloc(thread_seq, ptr, size); + } +#endif + + return realloc(ptr, size); +} + +/* ��ҵ�������ص�ֵת����ƽ̨�����ֵ, ����PROT_STATE_xxxת��ΪAPP_STATE_xxx */ +char biz_retval_to_platform(char biz_ret) +{ + char plat_ret = 0; + + if(biz_ret & PROT_STATE_GIVEME){ + plat_ret |= APP_STATE_GIVEME; + } + + if(biz_ret & PROT_STATE_DROPME){ + plat_ret |= APP_STATE_DROPME; + } + + if(biz_ret & PROT_STATE_DROPPKT){ + plat_ret |= APP_STATE_DROPPKT; + } + + return plat_ret; +} + +/* ��ƽ̨��stateֵת����ҵ������ֵ, ����OP_STATE_PENDINGתΪSESSION_STATE_PENDING */ +char plat_state_to_biz(char plat_state) +{ + char biz_ret = SESSION_STATE_CLOSE; + + switch(plat_state){ + case OP_STATE_PENDING: + biz_ret = SESSION_STATE_PENDING; + break; + + case OP_STATE_DATA: + biz_ret = SESSION_STATE_DATA; + break; + + case OP_STATE_CLOSE: + biz_ret = SESSION_STATE_CLOSE; + break; + + default: + break; + } + + return biz_ret; +} + +#ifdef __cplusplus +} +#endif + diff --git a/include/stream_inc/stream_inject.h b/include/stream_inc/stream_inject.h index dae40a0..d024fbe 100644 --- a/include/stream_inc/stream_inject.h +++ b/include/stream_inc/stream_inject.h @@ -1,214 +1,216 @@ -#ifndef _APP_STREAM_INJECT_H_
-#define _APP_STREAM_INJECT_H_
-
-#include <sys/types.h>
-#include <stdint.h>
-#include "stream_base.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define STREAM_INJECT_H_VERSION (20181108)
-
-
-/*
- CHN : ����GK��غ���
- ENG : to force terminate a stream;
-
- MESA_kill_tcp: use RST to terminate a TCP stream;
- MESA_kill_tcp_synack: send phony SYN/ACK packet to cheat client and server.
- MESA_kill_connection: for non-TCP stream, such as UDP stream, only available in serial mode.
-
- return value:
- >= 0: success.
- -1 : error.
-*/
-int MESA_kill_tcp(struct streaminfo *stream, const void *raw_pkt);
-int MESA_kill_tcp_synack(struct streaminfo *stream, const void *raw_pkt);
-int MESA_kill_connection(struct streaminfo *stream, const void *ext_raw_pkt);
-
-/*
- ���������ܵ�MESA_kill_xxxϵ�к���.
- ���ӹ���Ϊ:
- ��ʵ�ʷ��͵����ݰ�copy��feedback_buf�ռ���, ������feedback_buf_lenΪʵ�����ݰ�����.
-
- ע��: feedback_buf_lenΪ���봫����, �����ʾfeedback_buf����, ������ʾʵ�ʷ��͵����ݰ�����.
-
- return value:
- >= 0: success.
- -1 : error.
- -2 : feedback_buf or feedback_buf_len error.
-*/
-int MESA_kill_tcp_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len);
-int MESA_kill_tcp_synack_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len);
-int MESA_kill_connection_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len);
-
-/*
- CHN : ����route_dir����, Ϊ�˼���papp;
- ENG : compat for papp, dir reverse.
- */
-unsigned char MESA_dir_reverse(unsigned char raw_route_dir);
-
-/*
- ARG:
- stream: ���ṹ��ָ��;
- payload: Ҫ���͵�����ָ��;
- payload_len: Ҫ���͵����ݸ��س���;
- raw_pkt: ԭʼ��ָ��;
- snd_routedir: Ҫ�������ݵ�route����,
- ��������͵İ��뵱ǰ��ͬ��, snd_routedir = stream->routedir,
- ��������͵İ��뵱ǰ������, snd_routedir = MESA_dir_reverse(stream->routedir).
- return value:
- -1: error.
- >0: ���͵����ݰ�ʵ���ܳ���(payload_len + �ײ��ͷ����);
-*/
-int MESA_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len, const void *raw_pkt, UCHAR snd_routedir);
-
-
-/*
- ���������ܵ�MESA_inject_pkt_feedback����, ����ͬMESA_inject_pkt().
- ��ʵ�ʷ��͵����ݰ�copy��feedback_buf�ռ���, ������feedback_buf_lenΪʵ�����ݰ�����.
-
- ע��: feedback_buf_lenΪ���봫����, �����ʾfeedback_buf����, ������ʾʵ�ʷ��͵����ݰ�����.
-
- return value:
- >= 0: success.
- -1 : error.
- -2 : feedback_buf or feedback_buf_len error.
-*/
-int MESA_inject_pkt_feedback(struct streaminfo *stream, const char *payload, int payload_len,
- const void *ext_raw_pkt, UCHAR snd_routedir,
- char *feedback_buf, int *feedback_buf_len);
-
-int MESA_sendpacket_ethlayer(int thread_index,const char *buf, int buf_len, unsigned int target_id);//papp online, shuihu
-
-/* �����ѹ���õ�����IPv4��, IPv4ͷ��У��͵Ⱦ���������� */
-int MESA_sendpacket_iplayer(int thread_index,const char *buf, int buf_len, __uint8_t dir);
-
-/* �����ѹ���õ�����IPv4��, ����vxlan����, options��������vxlan��ص�ѡ�� */
-int MESA_sendpacket_iplayer_options(int thread_index,const char *data, int data_len, u_int8_t dir, SAPP_TLV_T *options, int opt_num);
-
-/* �����ѹ���õ�����IPv6��, У��͵Ⱦ����������, ����vxlan����, options��������vxlan��ص�ѡ�� */
-int MESA_sendpacket_ipv6_layer_options(int thread_index,const char *data, int data_len, u_int8_t dir, SAPP_TLV_T *options, int opt_num);
-
-/* ����ָ������IP��, ��ָ����������, У�����ƽ̨�Զ�����,
- sip, dip������. */
-int MESA_fakepacket_send_ipv4(int thread_index,__uint8_t ttl,__uint8_t protocol,
- u_int32_t sip_host_order, u_int32_t dip_host_order,
- const char *payload, int payload_len,__uint8_t dir);
-
-int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol,
- uint32_t sip_host_order, uint32_t dip_host_order,
- const char *payload, int payload_len, uint8_t dir,
- SAPP_TLV_T *options, int opt_num);
-
-int MESA_fakepacket_send_ipv4_detail(int thread_index,u_int8_t ttl,
- u_int8_t protocol,u_int32_t sip, u_int32_t dip, u_int16_t ipid,
- const char *payload, int payload_len,u_int8_t dir);
-
-int MESA_fakepacket_send_ipv6_options(const struct streaminfo *stream, uint8_t protocol,
- struct in6_addr *sip, struct in6_addr *dip,
- const char *payload, int payload_len, uint8_t dir,
- SAPP_TLV_T *options, int opt_num);
-
-/* ����ָ������TCP��, ��ָ����������, У�����ƽ̨�Զ�����,
- sip, dip,sport,dport,sseq,sack��������. */
-int MESA_fakepacket_send_tcp(int thread_index,u_int sip_host_order,u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control,const char* payload,int payload_len, u_int8_t dir);
-
-int MESA_fakepacket_send_tcp_detail(int thread_index,u_int sip_host_order,u_int dip_host_order,
- u_short ipid, u_char ip_ttl,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control, u_short tcp_win, const char* payload,int payload_len, u_int8_t dir);
-int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream,
- u_int sip_host_order,u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control,
- const char* payload,int payload_len, u_int8_t dir,
- SAPP_TLV_T *options, int opt_num);
-int MESA_fakepacket_send_ipv6_tcp_options(const struct streaminfo *stream,
- struct in6_addr *sip, struct in6_addr *dip,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control,
- const char* payload,int payload_len, u_int8_t dir,
- SAPP_TLV_T *options, int opt_num);
-/* ����ָ������UDP��, ��ָ����������, У�����ƽ̨�Զ�����,
- sip, dip,sport,dport��������. */
-int MESA_fakepacket_send_udp(int thread_index, u_int sip_host_order, u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir);
-
-int MESA_fakepacket_send_udp_detail(int thread_index, u_int sip_host_order, u_int dip_host_order,
- u_short ipid, u_int8_t ip_ttl, u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir);
-int MESA_fakepacket_send_udp_options(const struct streaminfo *stream,
- u_int sip_host_order, u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir,
- SAPP_TLV_T *options, int opt_num);
-int MESA_fakepacket_send_ipv6_udp_options(const struct streaminfo *stream,
- struct in6_addr *sip, struct in6_addr *dip,
- u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir,
- SAPP_TLV_T *options, int opt_num);
-/*
- ת��/���͵�ǰ���������ݰ�,
- target_id: ����ָ��ת��/����Ŀ��, �������ļ�conf->send_raw_pkt.confָ������Ŀ���������豸��.
-*/
-int sapp_forward_current_pkt(const struct streaminfo *stream, unsigned int target_id);
-
-enum sapp_send_pkt_opt_type{
- SAPP_SEND_OPT_IP_ID = 0x10,
- SAPP_SEND_OPT_IP_TTL = 0x11,
-
- SAPP_SEND_OPT_TCP_WIN = 0x20,
-
- SAPP_SEND_OPT_GDEV_DMAC = 0x1101, /* GDEV-DMAC, �������������DMAC */
- SAPP_SEND_OPT_GDEV_SMAC = 0x1102, /* local-SMAC, �������������SMAC */
- SAPP_SEND_OPT_GDEV_DIP = 0x1103, /* GDEV-DIP, network order */
- SAPP_SEND_OPT_GDEV_SIP = 0x1104, /* local-SIP, network order */
- SAPP_SEND_OPT_GDEV_UDP_DPORT=0x1105, /* GDEV udp dst port, network order */
- SAPP_SEND_OPT_GDEV_UDP_SPORT= 0x1106, /* local udp src port, network order */
- SAPP_SEND_OPT_VXLAN_FLAGS = 0x1201, /* vxlan ��־λ */
- SAPP_SEND_OPT_VXLAN_VPN_ID = 0x1202, /* vxlan vlan_id/vpn_id */
- SAPP_SEND_OPT_VXLAN_LINK_ID = 0x1203, /* vxlan ��·id */
- SAPP_SEND_OPT_VXLAN_LINK_ENCAP_TYPE = 0x1204, /* vxlanԭʼ�����װ��ʽ */
- SAPP_SEND_OPT_VXLAN_ONLINE_TEST_FLAG = 0x1205, /* vxlan���߲���λ */
- SAPP_SEND_OPT_VXLAN_LINK_DIR = 0x1206, /* vxlan��·����λ */
- SAPP_SEND_OPT_INNER_LINK_ENCAP_TYPE = 1301, /* �ڲ�����װ��ʽ */
- SAPP_SEND_OPT_INNER_SMAC = 0x1302, /* �ڲ�ԴMAC */
- SAPP_SEND_OPT_INNER_DMAC = 0x1303, /* �ڲ�Ŀ��MAC */
- SAPP_SEND_OPT_INNER_VLANID = 0x1304, /* �ڲ������VLAN������ */
-};
-
-int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol,
- uint32_t sip_host_order, uint32_t dip_host_order,
- const char *payload, int payload_len, uint8_t dir,
- SAPP_TLV_T *options, int opt_num);
-
-int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream,
- u_int sip_host_order,u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control,
- const char* payload,int payload_len, u_int8_t dir,
- SAPP_TLV_T *options, int opt_num);
-
-int MESA_fakepacket_send_udp_options(const struct streaminfo *stream,
- u_int sip_host_order, u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir,
- SAPP_TLV_T *options, int opt_num);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
+#ifndef _APP_STREAM_INJECT_H_ +#define _APP_STREAM_INJECT_H_ + +#include <sys/types.h> +#include <stdint.h> +#include "stream_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STREAM_INJECT_H_VERSION (20181108) + + +/* + CHN : ����GK��غ��� + ENG : to force terminate a stream; + + MESA_kill_tcp: use RST to terminate a TCP stream; + MESA_kill_tcp_synack: send phony SYN/ACK packet to cheat client and server. + MESA_kill_connection: for non-TCP stream, such as UDP stream, only available in serial mode. + + return value: + >= 0: success. + -1 : error. +*/ +int MESA_kill_tcp(struct streaminfo *stream, const void *raw_pkt); +int MESA_kill_tcp_synack(struct streaminfo *stream, const void *raw_pkt); +int MESA_kill_connection(struct streaminfo *stream, const void *ext_raw_pkt); + +/* + ���������ܵ�MESA_kill_xxxϵ�к���. + ���ӹ���Ϊ: + ��ʵ�ʷ��͵����ݰ�copy��feedback_buf�ռ���, ������feedback_buf_lenΪʵ�����ݰ�����. + + ע��: feedback_buf_lenΪ���봫����, �����ʾfeedback_buf����, ������ʾʵ�ʷ��͵����ݰ�����. + + return value: + >= 0: success. + -1 : error. + -2 : feedback_buf or feedback_buf_len error. +*/ +int MESA_kill_tcp_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len); +int MESA_kill_tcp_synack_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len); +int MESA_kill_connection_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len); + +/* + CHN : ����route_dir����, Ϊ�˼���papp; + ENG : compat for papp, dir reverse. + */ +unsigned char MESA_dir_reverse(unsigned char raw_route_dir); + +/* + ARG: + stream: ���ṹ��ָ��; + payload: Ҫ���͵�����ָ��; + payload_len: Ҫ���͵����ݸ��س���; + raw_pkt: ԭʼ��ָ��; + snd_routedir: Ҫ�������ݵ�route����, + ��������͵İ��뵱ǰ��ͬ��, snd_routedir = stream->routedir, + ��������͵İ��뵱ǰ������, snd_routedir = MESA_dir_reverse(stream->routedir). + return value: + -1: error. + >0: ���͵����ݰ�ʵ���ܳ���(payload_len + �ײ��ͷ����); +*/ +int MESA_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len, const void *raw_pkt, UCHAR snd_routedir); + + +/* + ���������ܵ�MESA_inject_pkt_feedback����, ����ͬMESA_inject_pkt(). + ��ʵ�ʷ��͵����ݰ�copy��feedback_buf�ռ���, ������feedback_buf_lenΪʵ�����ݰ�����. + + ע��: feedback_buf_lenΪ���봫����, �����ʾfeedback_buf����, ������ʾʵ�ʷ��͵����ݰ�����. + + return value: + >= 0: success. + -1 : error. + -2 : feedback_buf or feedback_buf_len error. +*/ +int MESA_inject_pkt_feedback(struct streaminfo *stream, const char *payload, int payload_len, + const void *ext_raw_pkt, UCHAR snd_routedir, + char *feedback_buf, int *feedback_buf_len); + +int MESA_sendpacket_ethlayer(int thread_index,const char *buf, int buf_len, unsigned int target_id);//papp online, shuihu + +/* �����ѹ���õ�����IPv4��, IPv4ͷ��У��͵Ⱦ���������� */ +int MESA_sendpacket_iplayer(int thread_index,const char *buf, int buf_len, __uint8_t dir); + +/* �����ѹ���õ�����IPv4��, ����vxlan����, options��������vxlan��ص�ѡ�� */ +int MESA_sendpacket_iplayer_options(int thread_index,const char *data, int data_len, u_int8_t dir, SAPP_TLV_T *options, int opt_num); + +/* �����ѹ���õ�����IPv6��, У��͵Ⱦ����������, ����vxlan����, options��������vxlan��ص�ѡ�� */ +int MESA_sendpacket_ipv6_layer_options(int thread_index,const char *data, int data_len, u_int8_t dir, SAPP_TLV_T *options, int opt_num); + +/* ����ָ������IP��, ��ָ����������, У�����ƽ̨�Զ�����, + sip, dipΪ������. */ +int MESA_fakepacket_send_ipv4(int thread_index,__uint8_t ttl,__uint8_t protocol, + u_int32_t sip_host_order, u_int32_t dip_host_order, + const char *payload, int payload_len,__uint8_t dir); + +int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol, + uint32_t sip_host_order, uint32_t dip_host_order, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num); + +int MESA_fakepacket_send_ipv4_detail(int thread_index,u_int8_t ttl, + u_int8_t protocol,u_int32_t sip, u_int32_t dip, u_int16_t ipid, + const char *payload, int payload_len,u_int8_t dir); + +int MESA_fakepacket_send_ipv6_options(const struct streaminfo *stream, uint8_t protocol, + struct in6_addr *sip, struct in6_addr *dip, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num); + +/* ����ָ������TCP��, ��ָ����������, У�����ƽ̨�Զ�����, + sip, dip,sport,dport,sseq,sack��Ϊ������. */ +int MESA_fakepacket_send_tcp(int thread_index,u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control,const char* payload,int payload_len, u_int8_t dir); + +int MESA_fakepacket_send_tcp_detail(int thread_index,u_int sip_host_order,u_int dip_host_order, + u_short ipid, u_char ip_ttl, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, u_short tcp_win, const char* payload,int payload_len, u_int8_t dir); +int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream, + u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +int MESA_fakepacket_send_ipv6_tcp_options(const struct streaminfo *stream, + struct in6_addr *sip, struct in6_addr *dip, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +/* ����ָ������UDP��, ��ָ����������, У�����ƽ̨�Զ�����, + sip, dip,sport,dport��Ϊ������. */ +int MESA_fakepacket_send_udp(int thread_index, u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir); + +int MESA_fakepacket_send_udp_detail(int thread_index, u_int sip_host_order, u_int dip_host_order, + u_short ipid, u_int8_t ip_ttl, u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir); +int MESA_fakepacket_send_udp_options(const struct streaminfo *stream, + u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +int MESA_fakepacket_send_ipv6_udp_options(const struct streaminfo *stream, + struct in6_addr *sip, struct in6_addr *dip, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +/* + ת��/���͵�ǰ���������ݰ�, + target_id: ����ָ��ת��/����Ŀ��, �������ļ�conf->send_raw_pkt.confָ������Ŀ���������豸��. +*/ +int sapp_forward_current_pkt(const struct streaminfo *stream, unsigned int target_id); + +enum sapp_send_pkt_opt_type{ + SAPP_SEND_OPT_IP_ID = 0x10, + SAPP_SEND_OPT_IP_TTL = 0x11, + + SAPP_SEND_OPT_TCP_WIN = 0x20, + + SAPP_SEND_OPT_GDEV_DMAC = 0x1101, /* GDEV-DMAC, �������������DMAC */ + SAPP_SEND_OPT_GDEV_SMAC = 0x1102, /* local-SMAC, �������������SMAC */ + SAPP_SEND_OPT_GDEV_DIP = 0x1103, /* GDEV-DIP, network order */ + SAPP_SEND_OPT_GDEV_SIP = 0x1104, /* local-SIP, network order */ + SAPP_SEND_OPT_GDEV_UDP_DPORT=0x1105, /* GDEV udp dst port, network order */ + SAPP_SEND_OPT_GDEV_UDP_SPORT= 0x1106, /* local udp src port, network order */ + SAPP_SEND_OPT_VXLAN_FLAGS = 0x1201, /* vxlan ��־λ */ + SAPP_SEND_OPT_VXLAN_VPN_ID = 0x1202, /* vxlan vlan_id/vpn_id */ + SAPP_SEND_OPT_VXLAN_LINK_ID = 0x1203, /* vxlan ��·id */ + SAPP_SEND_OPT_VXLAN_LINK_ENCAP_TYPE = 0x1204, /* vxlanԭʼ�����װ��ʽ */ + SAPP_SEND_OPT_VXLAN_ONLINE_TEST_FLAG = 0x1205, /* vxlan���߲���λ */ + SAPP_SEND_OPT_VXLAN_LINK_DIR = 0x1206, /* vxlan��·����λ */ + SAPP_SEND_OPT_INNER_LINK_ENCAP_TYPE = 1301, /* �ڲ�����װ��ʽ */ + SAPP_SEND_OPT_INNER_SMAC = 0x1302, /* �ڲ�ԴMAC */ + SAPP_SEND_OPT_INNER_DMAC = 0x1303, /* �ڲ�Ŀ��MAC */ + SAPP_SEND_OPT_INNER_VLANID = 0x1304, /* �ڲ������VLAN������ */ + SAPP_SEND_OPT_VIRTUAL_LINK_ID = 0x1305, /* ����������·�ţ� ͬʱ��Ҫ��TUNNAT_CZ_ACTION_ENCAP_VIRTUAL_LINK_ID*/ + SAPP_SEND_OPT_REHASH_INDEX = 0x1306, /*����rehash index�� ͬʱ��Ҫ��TUNNAT_CZ_ACTION_ENCAP_VIRTUAL_LINK_ID*/ +}; + +int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol, + uint32_t sip_host_order, uint32_t dip_host_order, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num); + +int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream, + u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num); + +int MESA_fakepacket_send_udp_options(const struct streaminfo *stream, + u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/stream_inc/stream_rawpkt.h b/include/stream_inc/stream_rawpkt.h index 1e9ea56..9be7002 100644 --- a/include/stream_inc/stream_rawpkt.h +++ b/include/stream_inc/stream_rawpkt.h @@ -1,106 +1,108 @@ -#ifndef _APP_STREAM_RAWPKT_H_
-#define _APP_STREAM_RAWPKT_H_
-
-#define STREAM_RAWPKT_H_VERSION (20181029)
-
-#include "stream_base.h"
-
-enum{
- RAW_PKT_GET_DATA = 1, //return value is 0: out_value should be void **; return value is 1: out_value type is raw_ipfrag_list_t **;
- RAW_PKT_GET_RAW_PKT_TYPE, //value type: enum addr_type_t in stream_base.h, out_value should be enum addr_type_t*
- RAW_PKT_GET_TOT_LEN, //value type: int , out_value should be int *
- RAW_PKT_GET_TIMESTAMP, //value type: struct timeval , out_value should be struct timeval *
- RAW_PKT_GET_THIS_LAYER_HDR, //value type: void *, out_value should be void **
- RAW_PKT_GET_THIS_LAYER_REMAIN_LEN, //value type: int , out_value should be int *
-
- RAW_PKT_GET_GDEV_IP, // network-order, value type is int, out_value should be int *
- RAW_PKT_GET_VXLAN_ID, // network-order, LINK_ID, not VPN_ID, value type is int, out_value should be int *
- RAW_PKT_GET_VXLAN_SPORT, // network-order, value type is short, out_value should be short *
- RAW_PKT_GET_VXLAN_ENCAP_TYPE, //value type is char,
- RAW_PKT_GET_VXLAN_LINK_DIR, //value type is char,
- RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC, //value type is char[6],
- RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC, //value type is char[6],
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- get option from raw packet.
-
-for example:
- CHN : ��ȡԭʼ������, (���ݲ������͵IJ�ͬ, ���ܴ�MAC��ʼ, Ҳ���ܴ�IPͷ����ʼ, ��Ҫʹ��RAW_PKT_GET_RAW_PKT_TYPE��ȡ);
- ENG : get raw packet header, header's type depend on raw pacekt type, you should use RAW_PKT_GET_RAW_PKT_TYPE first;
-
- void *raw_pkt_data;
- ret = get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_DATA, &raw_pkt_data);
- if(0 == ret){
- (struct mesa_ethernet_hdr *)raw_pkt_data;
- }else if(1 == ret){
- (raw_ipfrag_list_t *)raw_pkt_data;
- }else{
- error!
- }
-
- CHN : ��ȡԭʼ���ܳ���;
- ENG : get raw packet size;
- int tot_len;
- get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TOT_LEN, &tot_len);
-
- CHN : ��ȡ�����ͷ��ʼ��ַ:
- ENG : get this layer header;
- void *this_layer_hdr;
- get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_THIS_LAYER_HDR, &this_layer_hdr);
-
- CHN : ��ȡԭʼ��ʱ���, ���������ײ㲶���ⲻ֧��ʱ�������, ֵΪȫ0:
- ENG : get raw packet timestamp, maybe zero if network card or library not support.
- struct timeval pkt_stamp;
- get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TIMESTAMP, &pkt_stamp);
-
- return value:
- 1:only for RAW_PKT_GET_DATA type, value is raw_ipfrag_list_t;
- 0:success;
- -1:error, or not support.
-*/
-int get_opt_from_rawpkt(const void *rawpkt, int type, void *out_value);
-
-/*
- CHN: ����ͬ��, ���������ͬ.
- ENG: Function ibid, except args pstream.
-*/
-int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value);
-
-/*
- ��ȡ��������ԭʼ���ж�Ӧ��ͷ����ַ,
- ���豾��������ΪTCP, ���ô˺�����, �õ�ԭʼ���ж�Ӧ��TCPͷ����ַ.
-*/
-const void *get_this_layer_header(const struct streaminfo *pstream);
-
-/*
- CHN : ���ݰ�ͷ��ƫ�ƺ���.
- ENG :
-
- ����:
- raw_data: ��ǰ���ͷ��ָ��;
- raw_layer_type: ��ǰ��ĵ�ַ����;
- expect_layer_type: ������ת���ĵ�ַ����;
-
- ����ֵ:
- NULL: �˵�ַ;
- NON-NULL: ��Ӧ���ͷ����ַ.
-
-
- ����:
- ���赱ǰ��ΪEthernet, ��ʼ��ͷ��ַΪthis_layer_hdr, ����ת��IPv6��ͷ��:
- struct ip6_hdr *ip6_header;
- ip6_header = MESA_net_jump_to_layer(this_layer_hdr, ADDR_TYPE_MAC, ADDR_TYPE_IPV6);
-*/
-const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, int expect_layer_type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
+#ifndef _APP_STREAM_RAWPKT_H_ +#define _APP_STREAM_RAWPKT_H_ + +#define STREAM_RAWPKT_H_VERSION (20181029) + +#include "stream_base.h" + +enum{ + RAW_PKT_GET_DATA = 1, //return value is 0: out_value should be void **; return value is 1: out_value type is raw_ipfrag_list_t **; + RAW_PKT_GET_RAW_PKT_TYPE, //value type: enum addr_type_t in stream_base.h, out_value should be enum addr_type_t* + RAW_PKT_GET_TOT_LEN, //value type: int , out_value should be int * + RAW_PKT_GET_TIMESTAMP, //value type: struct timeval , out_value should be struct timeval * + RAW_PKT_GET_THIS_LAYER_HDR, //value type: void *, out_value should be void ** + RAW_PKT_GET_THIS_LAYER_REMAIN_LEN, //value type: int , out_value should be int * + + RAW_PKT_GET_GDEV_IP, // network-order, value type is int, out_value should be int * + RAW_PKT_GET_VXLAN_ID, // network-order, LINK_ID, not VPN_ID, value type is int, out_value should be int * + RAW_PKT_GET_VXLAN_SPORT, // network-order, value type is short, out_value should be short * + RAW_PKT_GET_VXLAN_ENCAP_TYPE, //value type is char, + RAW_PKT_GET_VXLAN_LINK_DIR, //value type is char, + RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC, //value type is char[6], + RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC, //value type is char[6], + RAW_PKT_GET_VIRTUAL_LINK_ID, //value type is uint64 *, out_value should be uint64 * + RAW_PKT_GET_REHASH_INDEX // value type is uint64 *, out_value should be uint64 * +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + get option from raw packet. + +for example: + CHN : ��ȡԭʼ������, (���ݲ������͵IJ�ͬ, ���ܴ�MAC��ʼ, Ҳ���ܴ�IPͷ����ʼ, ��Ҫʹ��RAW_PKT_GET_RAW_PKT_TYPE��ȡ); + ENG : get raw packet header, header's type depend on raw pacekt type, you should use RAW_PKT_GET_RAW_PKT_TYPE first; + + void *raw_pkt_data; + ret = get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_DATA, &raw_pkt_data); + if(0 == ret){ + (struct mesa_ethernet_hdr *)raw_pkt_data; + }else if(1 == ret){ + (raw_ipfrag_list_t *)raw_pkt_data; + }else{ + error! + } + + CHN : ��ȡԭʼ���ܳ���; + ENG : get raw packet size; + int tot_len; + get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TOT_LEN, &tot_len); + + CHN : ��ȡ�����ͷ��ʼ��ַ: + ENG : get this layer header; + void *this_layer_hdr; + get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_THIS_LAYER_HDR, &this_layer_hdr); + + CHN : ��ȡԭʼ��ʱ���, ���������ײ㲶���ⲻ֧��ʱ�������, ֵΪȫ0: + ENG : get raw packet timestamp, maybe zero if network card or library not support. + struct timeval pkt_stamp; + get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TIMESTAMP, &pkt_stamp); + + return value: + 1:only for RAW_PKT_GET_DATA type, value is raw_ipfrag_list_t; + 0:success; + -1:error, or not support. +*/ +int get_opt_from_rawpkt(const void *rawpkt, int type, void *out_value); + +/* + CHN: ����ͬ��, ���������ͬ. + ENG: Function ibid, except args pstream. +*/ +int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value); + +/* + ��ȡ��������ԭʼ���ж�Ӧ��ͷ����ַ, + ���豾��������ΪTCP, ���ô˺�����, �õ�ԭʼ���ж�Ӧ��TCPͷ����ַ. +*/ +const void *get_this_layer_header(const struct streaminfo *pstream); + +/* + CHN : ���ݰ�ͷ��ƫ�ƺ���. + ENG : + + ����: + raw_data: ��ǰ���ͷ��ָ��; + raw_layer_type: ��ǰ��ĵ�ַ����; + expect_layer_type: ������ת���ĵ�ַ����; + + ����ֵ: + NULL: �˵�ַ; + NON-NULL: ��Ӧ���ͷ����ַ. + + + ����: + ���赱ǰ��ΪEthernet, ��ʼ��ͷ��ַΪthis_layer_hdr, ����ת��IPv6��ͷ��: + struct ip6_hdr *ip6_header; + ip6_header = MESA_net_jump_to_layer(this_layer_hdr, ADDR_TYPE_MAC, ADDR_TYPE_IPV6); +*/ +const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, int expect_layer_type); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/support/mrtunnat_for_view.h b/include/support/mrtunnat_for_view.h index 1eddfa5..e2b0b3a 100644 --- a/include/support/mrtunnat_for_view.h +++ b/include/support/mrtunnat_for_view.h @@ -1,70 +1,77 @@ -#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-enum {
-
- /* ���Ļ�ע */
- TUNNAT_CZ_ACTION_FORWARD = ( 1 << 0 ),
- /* �ڲ�������װ�����ø�ѡ������ظ����װMACͷ�� */
- TUNNAT_CZ_ACTION_ENCAP_INNER = ( 1 << 1 ),
- /* ���������װ�����ø�ѡ������ظ����װר���豸����װ */
- TUNNAT_CZ_ACTION_ENCAP_OUTER = ( 1 << 2 ),
- /* ������װ������ֱ�ӹ���������ѯSession�� */
- TUNNAT_CZ_ACTION_ENCAP_NO_SESSION = ( 1 << 3 )
-};
-
-enum
-{
- TUNNAT_TUNNEL_TYPE_UNKNOWN,
- TUNNAT_TUNNEL_TYPE_G_VXLAN,
- TUNNAT_TUNNEL_TYPE_G_MAC_IN_MAC,
- TUNNAT_TUNNEL_TYPE_ETHER,
- TUNNAT_TUNNEL_TYPE_PPP,
- TUNNAT_TUNNEL_TYPE_HDLC,
- TUNNAT_TUNNEL_TYPE_IPV4,
- TUNNAT_TUNNEL_TYPE_IPV6
-};
-
-struct mr_tunnat_ctrlzone
-{
- /* ��װ��ʽ���ڲ�ʹ�ã�Ӧ�ó���ʹ�� */
- uint8_t __encap_type;
- /* ��װ���ȣ��ڲ�ʹ�ã�Ӧ�ó���ʹ�� */
- uint16_t __encap_len;
- /* α��̫��ͷ���������ݣ��ڲ�ʹ�ã�Ӧ�ó���ʹ�� */
- uint16_t __p_ether_type;
-
- /* ����C-I��I-C���� */
- uint8_t route_dir;
- /* ��������ACTIONϵ�к� */
- uint8_t action;
-
- /* ר���豸MAC��ַ */
- uint8_t g_device_mac[6];
- /* �����豸MAC��ַ */
- uint8_t l_device_mac[6];
- /* ר���豸IP��ַ */
- uint32_t g_device_in_addr;
- /* �����豸IP��ַ */
- uint32_t l_device_in_addr;
- /* �����豸�˿� */
- uint16_t l4_src_port;
-
- /* ר���豸VPN�� */
- uint32_t g_device_vpn_id;
- /* ר���豸��·ID�� */
- uint32_t g_device_linkpair;
- /* ר���豸��װ��ʽ����㣩 */
- uint8_t g_device_outer_encap_type;
- /* ר���豸��װ��ʽ���ڲ㣩*/
- uint8_t g_device_inner_encap_type;
-};
-
-#ifdef __cplusplus
-}
+#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +enum { + + /* ���Ļ�ע */ + TUNNAT_CZ_ACTION_FORWARD = ( 1 << 0 ), + /* �ڲ�������װ�����ø�ѡ������ظ����װMACͷ�� */ + TUNNAT_CZ_ACTION_ENCAP_INNER = ( 1 << 1 ), + /* ���������װ�����ø�ѡ������ظ����װר���豸����װ */ + TUNNAT_CZ_ACTION_ENCAP_OUTER = ( 1 << 2 ), + /* ������װ������ֱ�ӹ���������ѯSession�� */ + TUNNAT_CZ_ACTION_ENCAP_NO_SESSION = ( 1 << 3 ) + /* ʹ��������·�ŷ�װ */ + TUNNAT_CZ_ACTION_ENCAP_VIRTUAL_LINK_ID = ( 1 << 4), +}; + +enum +{ + TUNNAT_TUNNEL_TYPE_UNKNOWN, + TUNNAT_TUNNEL_TYPE_G_VXLAN, + TUNNAT_TUNNEL_TYPE_G_MAC_IN_MAC, + TUNNAT_TUNNEL_TYPE_ETHER, + TUNNAT_TUNNEL_TYPE_PPP, + TUNNAT_TUNNEL_TYPE_HDLC, + TUNNAT_TUNNEL_TYPE_IPV4, + TUNNAT_TUNNEL_TYPE_IPV6 +}; + +struct mr_tunnat_ctrlzone +{ + /* ��װ��ʽ���ڲ�ʹ�ã�Ӧ�ó���ʹ�� */ + uint8_t __encap_type; + /* ��װ���ȣ��ڲ�ʹ�ã�Ӧ�ó���ʹ�� */ + uint16_t __encap_len; + /* α��̫��ͷ���������ݣ��ڲ�ʹ�ã�Ӧ�ó���ʹ�� */ + uint16_t __p_ether_type; + + /* ����C-I��I-C���� */ + uint8_t route_dir; + /* ��������ACTIONϵ�к� */ + uint8_t action; + + /* ר���豸MAC��ַ */ + uint8_t g_device_mac[6]; + /* �����豸MAC��ַ */ + uint8_t l_device_mac[6]; + /* ר���豸IP��ַ */ + uint32_t g_device_in_addr; + /* �����豸IP��ַ */ + uint32_t l_device_in_addr; + /* �����豸�˿� */ + uint16_t l4_src_port; + + /* ר���豸VPN�� */ + uint32_t g_device_vpn_id; + /* ר���豸��·ID�� */ + uint32_t g_device_linkpair; + /* ר���豸��װ��ʽ����㣩 */ + uint8_t g_device_outer_encap_type; + /* ר���豸��װ��ʽ���ڲ㣩*/ + uint8_t g_device_inner_encap_type; + + /* ������·�� */ + uint64_t virtual_link_id; + /* �����ؼ������� */ + uint64_t rehash_index; +}; + +#ifdef __cplusplus +} #endif
\ No newline at end of file diff --git a/inner_plug/CMakeLists.txt b/inner_plug/CMakeLists.txt index abdb822..390aa7a 100644 --- a/inner_plug/CMakeLists.txt +++ b/inner_plug/CMakeLists.txt @@ -10,6 +10,10 @@ include_directories(${CMAKE_SOURCE_DIR}/include/support) include_directories(${CMAKE_SOURCE_DIR}/include/stream_inc) include_directories(${CMAKE_SOURCE_DIR}/dealpkt) +if(OPT_IOMODE_MARSIO) + include_directories(${MARSIO_SDK_PREFIX}/include) +endif() + add_definitions(-D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H) add_definitions(-fPIC) diff --git a/inner_plug/Makefile b/inner_plug/Makefile index ab9702e..ba1bd10 100644 --- a/inner_plug/Makefile +++ b/inner_plug/Makefile @@ -22,6 +22,7 @@ H_DIR += -I../dealpkt H_DIR += -I../packet_io H_DIR += -I/opt/MESA/include H_DIR += -I/opt/MESA/include/MESA +H_DIR += -I/opt/mrzcpd/include LIB=-L/opt/MESA/lib diff --git a/packet_io/CMakeLists.txt b/packet_io/CMakeLists.txt index 5c6233b..87c4eb8 100644 --- a/packet_io/CMakeLists.txt +++ b/packet_io/CMakeLists.txt @@ -11,6 +11,10 @@ include_directories(${CMAKE_SOURCE_DIR}/include/support) include_directories(${CMAKE_SOURCE_DIR}/dealpkt) include_directories(${CMAKE_SOURCE_DIR}/packet_io) +if(OPT_IOMODE_MARSIO) + include_directories(${MARSIO_SDK_PREFIX}/include) +endif() + add_definitions(-fPIC) if(CAPTURE_MODE MATCHES "PCAP") @@ -36,14 +40,19 @@ endif() if(CAPTURE_MODE MATCHES "MARSIO") set(PACKET_IO_SOURCE ${PACKET_IO_SOURCE} packet_io_marsio.c) add_library(packet_io_marsio SHARED ${PACKET_IO_SOURCE}) + target_link_libraries(packet_io_marsio marsio) + set_target_properties(packet_io_marsio PROPERTIES PREFIX "") endif() set(PACKET_IO_STATIC_SOURCE cycle_pkt_dump_through_write_offset.c packet_io_lib_load.c pkt_dispatch_new.c iknow_info.c packet_io_log.c sendpacket.c -sendpacket_wrap.c packet_io.c packet_io_device.c +sendpacket_wrap.c packet_io.c packet_io_device.c sapp_compat_wangyan_api.c #packet_io_status_by_mesafs.cpp packet_io_status.cpp packet_io_status_new.c ) packet_io_status.cpp packet_io_status_new.c ) add_library(packet_io STATIC ${PACKET_IO_STATIC_SOURCE}) +if(CAPTURE_MODE MATCHES "MARSIO") + target_link_libraries(packet_io marsio) +endif() target_link_libraries(packet_io timestamp_record iknow) diff --git a/packet_io/Makefile b/packet_io/Makefile index 5787d2d..8441798 100644 --- a/packet_io/Makefile +++ b/packet_io/Makefile @@ -1,173 +1,174 @@ -#opt: OPTFLAGS = -O2
-#export OPTFLAGS
-
-#CC = g++
-#CCC = g++
-CFLAGS += -Wall
-CFLAGS += -fPIC -shared -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H
-CFLAGS += $(OPTFLAGS)
-CFLAGS += $(PACKET_TAG_863)
-CFLAGS += -DPLATFORM_NSDPF_PAPP=1
-
-ifeq ($(USE_PAG_GET_FRAME), 1)
-CFLAGS += -DUSE_PAG_GET_FRAME=1
-endif
-
-RELEASE_PATH=../run/platform_lib/
-LIBPATH = -L../lib
-DEP = ../support/libnet_common.so
-
-H_DIR += $(INC)
-H_DIR += -I../include
-H_DIR += -I../include/net
-H_DIR += -I../include/support
-H_DIR += -I../include/stream_inc
-H_DIR += -I../include/packet_io_lib_inc
-H_DIR += -I../dealpkt
-H_DIR += -I/opt/MESA/include
-H_DIR += -I/opt/MESA/include/MESA
-
-DLL_LIB=
-ifeq ($(iomode), $(_MODE_PCAP))
-CFLAGS += -DIOMODE_PCAP=1
-DLL_LIB += packet_io_pcap.so
-endif
-
-ifeq ($(iomode), $(_MODE_PAG))
-CFLAGS += -DIOMODE_PAG=1
-DLL_LIB += packet_io_pag.so
-endif
-
-ifeq ($(iomode), $(_MODE_PPF))
-CFLAGS += -DIOMODE_PPF=1
-DLL_LIB += packet_io_ppf.so
-endif
-
-ifeq ($(iomode), $(_MODE_PFRING))
-CFLAGS += -DIOMODE_PFRING=1
-DLL_LIB += packet_io_pfring.so
-endif
-
-ifeq ($(iomode), $(_MODE_DPDK))
-CFLAGS += -DIOMODE_DPDK=1
-DLL_LIB += packet_io_dpdk.so
-endif
-
-ifeq ($(iomode), $(_MODE_TOPSEC))
-CFLAGS += -DIOMODE_TOPSEC=1
-DLL_LIB += packet_io_topsec.so
-endif
-
-ifeq ($(iomode), $(_MODE_IPFILE))
-CFLAGS += -DIOMODE_IPFILE=1
-DLL_LIB += packet_io_ipfile.so
-endif
-
-ifeq ($(iomode), $(_MODE_MARSIO))
-DLL_LIB += packet_io_marsio.so
-CFLAGS += -DIOMODE_MARSIO=1
-endif
-
-ifeq ($(iomode), $(_MODE_SMITH))
-CFLAGS += -DIOMODE_SMITH=1
-DLL_LIB += packet_io_agent_smith.so
-endif
-
-ifeq ($(IIEFD_DUAL_STACK), $(YES))
-CFLAGS += -g -DIIEFD_DUAL_STACK=1
-endif
-
-ifeq ($(iomode), $(_MODE_DPDK_VXLAN))
-CFLAGS += -DIOMODE_DPDK_VXLAN=1
-DLL_LIB += packet_io_dpdk_vxlan.so
-endif
-
-ifeq ($(iomode), $(_MODE_PAG_MARSIO))
-CFLAGS += -DIOMODE_PAG_MARSIO=1
-DLL_LIB += packet_io_pag_marsio.so
-endif
-
-
-TARGET = libpacket_io.a
-
-OBJS=sendpacket.o sendpacket_wrap.o packet_io.o packet_io_log.o
-OBJS+=packet_io_lib_load.o
-OBJS+=packet_io_status.o
-OBJS+=packet_io_status_new.o
-#OBJS += cycle_pkt_dump.o
-#OBJS += cycle_pkt_dump_unix.o
-OBJS += cycle_pkt_dump_through_write_offset.o
-OBJS += packet_io_device.o
-OBJS += sapp_compat_wangyan_api.o
-
-ifeq ($(debug), $(_DEBUG2))
-OBJS += iknow_info.o
-endif
-
-all: $(TARGET) $(DLL_LIB)
-
-.c.o:
- $(CC) -c $(CFLAGS) -I. $(H_DIR) $<
-
-.cpp.o:
- $(CCC) -c $(CFLAGS) -I. $(H_DIR) $<
-
-
-$(TARGET): $(OBJS)
- rm -f $@ ;ar -r $@ $^;
- cp $(TARGET) ../lib
-
-packet_io_pcap.so:packet_io_pcap.o
- $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lpcap;
- cp $@ $(RELEASE_PATH)
-
-packet_io_pag.so:packet_io_pag.o
- #$(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lpag;
- gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lpag;
- cp $@ $(RELEASE_PATH)
-
-packet_io_ppf.so:packet_io_ppf.o
- $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lppf;
- cp $@ $(RELEASE_PATH)
-
-packet_io_pfring.so:packet_io_pfring.o
- $(CC) -o $@ -fPIC -shared -g -Wall $^ $(IBPATH) $(LIBS) -lpfring;
- cp $@ $(RELEASE_PATH)
-
-packet_io_qnf.so:packet_io_qnf.o
- $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lqnfapi;
- cp $@ $(RELEASE_PATH)
-
-packet_io_dpdk.so:packet_io_dpdk.o
- $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio;
- cp $@ $(RELEASE_PATH)
-
-packet_io_topsec.so:packet_io_topsec.o
- gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lpag;
- cp $@ $(RELEASE_PATH)
-
-packet_io_ipfile.so:packet_io_ipfile.o
- gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH);
- cp $@ $(RELEASE_PATH)
-
-packet_io_agent_smith.so:packet_io_agent_smith.o
- gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lagent_smith;
- cp $@ $(RELEASE_PATH)
-
-packet_io_marsio.so:packet_io_marsio.o
- gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio;
- cp $@ $(RELEASE_PATH)
-
-packet_io_dpdk_vxlan.so:packet_io_dpdk_vxlan.o
- $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio;
- cp $@ $(RELEASE_PATH)
-
-packet_io_pag_marsio.so:packet_io_pag_marsio.o
- gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio;
- cp $@ $(RELEASE_PATH)
-
-clean:
- rm -f *.o packet_io*.so *.a $(TARGET) $(DLL_LIB) *~
-
-opt:
- $(MAKE) all
+#opt: OPTFLAGS = -O2 +#export OPTFLAGS + +#CC = g++ +#CCC = g++ +CFLAGS += -Wall +CFLAGS += -fPIC -shared -D_BSD_SOURCE -D_BSD_SOURCE -D__BSD_SOURCE -D__FAVOR_BSD -DHAVE_NET_ETHERNET_H +CFLAGS += $(OPTFLAGS) +CFLAGS += $(PACKET_TAG_863) +CFLAGS += -DPLATFORM_NSDPF_PAPP=1 + +ifeq ($(USE_PAG_GET_FRAME), 1) +CFLAGS += -DUSE_PAG_GET_FRAME=1 +endif + +RELEASE_PATH=../run/platform_lib/ +LIBPATH = -L../lib +DEP = ../support/libnet_common.so + +H_DIR += $(INC) +H_DIR += -I../include +H_DIR += -I../include/net +H_DIR += -I../include/support +H_DIR += -I../include/stream_inc +H_DIR += -I../include/packet_io_lib_inc +H_DIR += -I../dealpkt +H_DIR += -I/opt/MESA/include +H_DIR += -I/opt/MESA/include/MESA +H_DIR += -I/opt/mrzcpd/include + +DLL_LIB= +ifeq ($(iomode), $(_MODE_PCAP)) +CFLAGS += -DIOMODE_PCAP=1 +DLL_LIB += packet_io_pcap.so +endif + +ifeq ($(iomode), $(_MODE_PAG)) +CFLAGS += -DIOMODE_PAG=1 +DLL_LIB += packet_io_pag.so +endif + +ifeq ($(iomode), $(_MODE_PPF)) +CFLAGS += -DIOMODE_PPF=1 +DLL_LIB += packet_io_ppf.so +endif + +ifeq ($(iomode), $(_MODE_PFRING)) +CFLAGS += -DIOMODE_PFRING=1 +DLL_LIB += packet_io_pfring.so +endif + +ifeq ($(iomode), $(_MODE_DPDK)) +CFLAGS += -DIOMODE_DPDK=1 +DLL_LIB += packet_io_dpdk.so +endif + +ifeq ($(iomode), $(_MODE_TOPSEC)) +CFLAGS += -DIOMODE_TOPSEC=1 +DLL_LIB += packet_io_topsec.so +endif + +ifeq ($(iomode), $(_MODE_IPFILE)) +CFLAGS += -DIOMODE_IPFILE=1 +DLL_LIB += packet_io_ipfile.so +endif + +ifeq ($(iomode), $(_MODE_MARSIO)) +DLL_LIB += packet_io_marsio.so +CFLAGS += -DIOMODE_MARSIO=1 +endif + +ifeq ($(iomode), $(_MODE_SMITH)) +CFLAGS += -DIOMODE_SMITH=1 +DLL_LIB += packet_io_agent_smith.so +endif + +ifeq ($(IIEFD_DUAL_STACK), $(YES)) +CFLAGS += -g -DIIEFD_DUAL_STACK=1 +endif + +ifeq ($(iomode), $(_MODE_DPDK_VXLAN)) +CFLAGS += -DIOMODE_DPDK_VXLAN=1 +DLL_LIB += packet_io_dpdk_vxlan.so +endif + +ifeq ($(iomode), $(_MODE_PAG_MARSIO)) +CFLAGS += -DIOMODE_PAG_MARSIO=1 +DLL_LIB += packet_io_pag_marsio.so +endif + + +TARGET = libpacket_io.a + +OBJS=sendpacket.o sendpacket_wrap.o packet_io.o packet_io_log.o +OBJS+=packet_io_lib_load.o +OBJS+=packet_io_status.o +OBJS+=packet_io_status_new.o +#OBJS += cycle_pkt_dump.o +#OBJS += cycle_pkt_dump_unix.o +OBJS += cycle_pkt_dump_through_write_offset.o +OBJS += packet_io_device.o +OBJS += sapp_compat_wangyan_api.o + +ifeq ($(debug), $(_DEBUG2)) +OBJS += iknow_info.o +endif + +all: $(TARGET) $(DLL_LIB) + +.c.o: + $(CC) -c $(CFLAGS) -I. $(H_DIR) $< + +.cpp.o: + $(CCC) -c $(CFLAGS) -I. $(H_DIR) $< + + +$(TARGET): $(OBJS) + rm -f $@ ;ar -r $@ $^; + cp $(TARGET) ../lib + +packet_io_pcap.so:packet_io_pcap.o + $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lpcap; + cp $@ $(RELEASE_PATH) + +packet_io_pag.so:packet_io_pag.o + #$(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lpag; + gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lpag; + cp $@ $(RELEASE_PATH) + +packet_io_ppf.so:packet_io_ppf.o + $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lppf; + cp $@ $(RELEASE_PATH) + +packet_io_pfring.so:packet_io_pfring.o + $(CC) -o $@ -fPIC -shared -g -Wall $^ $(IBPATH) $(LIBS) -lpfring; + cp $@ $(RELEASE_PATH) + +packet_io_qnf.so:packet_io_qnf.o + $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -lqnfapi; + cp $@ $(RELEASE_PATH) + +packet_io_dpdk.so:packet_io_dpdk.o + $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio; + cp $@ $(RELEASE_PATH) + +packet_io_topsec.so:packet_io_topsec.o + gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lpag; + cp $@ $(RELEASE_PATH) + +packet_io_ipfile.so:packet_io_ipfile.o + gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH); + cp $@ $(RELEASE_PATH) + +packet_io_agent_smith.so:packet_io_agent_smith.o + gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lagent_smith; + cp $@ $(RELEASE_PATH) + +packet_io_marsio.so:packet_io_marsio.o + gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio; + cp $@ $(RELEASE_PATH) + +packet_io_dpdk_vxlan.so:packet_io_dpdk_vxlan.o + $(CC) -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio; + cp $@ $(RELEASE_PATH) + +packet_io_pag_marsio.so:packet_io_pag_marsio.o + gcc -o $@ -fPIC -shared -g -Wall $^ $(LIBPATH) $(LIBS) -L$(LIBPATH) -lmarsio; + cp $@ $(RELEASE_PATH) + +clean: + rm -f *.o packet_io*.so *.a $(TARGET) $(DLL_LIB) *~ + +opt: + $(MAKE) all diff --git a/packet_io/sendpacket.c b/packet_io/sendpacket.c index 96a9a7f..27a6a92 100644 --- a/packet_io/sendpacket.c +++ b/packet_io/sendpacket.c @@ -1,3519 +1,3529 @@ -#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "sysinfo.h"
-#include "mesa_net.h"
-#include "stream_internal.h"
-#include "packet_io_internal.h"
-#include "packet_io.h"
-#include <MESA/MESA_handle_logger.h>
-#include <netinet/if_ether.h>
-#include <netinet/in.h>
-#include <net/if_arp.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-
-#define KILL_TCP_RST_NUM (3)
-#define KILL_TCP_SYN_ACK_NUM (3)
-
-typedef struct{
- UINT32 gateway_ip; /* network order */
- UINT8 gateway_mac[ETHER_ADDR_LEN];
- char to_gateway_device_name[DEV_NAME_STR_LEN];
-}sys_route_t;
-
-//static sys_route_t g_sys_route_info;
-MESA_send_handle g_send_handle[MAX_THREAD_NUM];
-static volatile UINT64 g_rand_seed = 0x013579ABCDEF;
-
-/* ������ƽ̨����randֵ���㷨, ����У��RST���Ƿ�Ϊ��ϵͳ���� */
-static int randgroup[MAX_THREAD_NUM];
-static int g_iRandKey=13;
-static int g_iMaxRandVal=65535;
-
-typedef struct{
- unsigned char ip_ttl;
- unsigned short ip_id_host_order;
- char __cache_align_pad_[60]; /* ���߳�ȫ�ֱ���, ��֤64�ֽ�cache����߽� */
-}bulid_layer_ipv4_args_t;
-
-typedef struct{
- int to_do;
-}bulid_layer_ipv6_args_t;
-
-typedef struct{
- unsigned char tcp_flags;
- unsigned short tcp_win_host_order;
- unsigned int tcp_seq;
- char __cache_align_pad_[56]; /* ���߳�ȫ�ֱ���, ��֤64�ֽ�cache����߽� */
-}bulid_layer_tcp_args_t;
-
-
-typedef struct{
- unsigned char ip_ttl;
- unsigned short ip_id_host_order;
- unsigned short tcp_win_host_order;
- char __cache_align_pad_[58]; /* ���߳�ȫ�ֱ���, ��֤64�ֽ�cache����߽� */
-}tcp_rst_finger_mark_t;
-
-static bulid_layer_ipv4_args_t g_build_ipv4_args[MAX_THREAD_NUM];
-//static bulid_layer_ipv6_args_t g_build_ipv6_args[MAX_THREAD_NUM];
-static bulid_layer_tcp_args_t g_build_tcp_args[MAX_THREAD_NUM];
-static layer_args_t g_build_pkt_args[MAX_THREAD_NUM];
-
-static tcp_rst_finger_mark_t g_tcp_rst_finger[MAX_THREAD_NUM];
-
-extern void *g_packet_dl_send_handle[MAX_THREAD_NUM];
-extern dl_io_fun_list_t dl_io_fun_list;
-extern char g_send_dev_name[DEV_NAME_STR_LEN];
-extern int g_packet_io_ipv6_switch;
-extern int g_packet_io_ipv6_raw_socket;
-extern int g_app_send_rst_type ;
-extern int g_packet_io_cap_level;
-extern int calc_l2tp_hdr_len(const struct l2tp_hdr_v2 *l2tp_hdr);
-extern int packet_io_send_fake_pkt(MESA_send_handle *send_handle,int datalen,int send_type,
- int low_layer_type, int dir,int thread_num,
- char *feedback_buf, int *feedback_buf_len);
-static inline int dir_check(unsigned char raw_dir);
-
-
-/*
- �����յ����ֽ��������ϸ����ij��Ȳ�����ݰ��ĵ�ַ����, �õ����������������.
-*/
-#if 0
-void random_seed(int pkt_len, UINT64 *pkt_rand)
-{
- static int last_pkt_len = 0x1234567;
- int diff = (pkt_len >= last_pkt_len)?(pkt_len-last_pkt_len):(last_pkt_len-pkt_len);
-
- g_rand_seed += (UINT64)pkt_len + (UINT64)diff + *pkt_rand;
-
- last_pkt_len = pkt_len;
-}
-#endif
-
-
-UINT64 MESA_rand(void)
-{
- return g_rand_seed ^ (UINT64)random();
-}
-
-/* return value: [start, end] */
-UINT64 MESA_rand_range(UINT64 start, UINT64 end)
-{
- UINT64 rand_num = MESA_rand();
-
- if(start > end){
- return end + rand_num % (start - end + 1);
- }
-
- return start + rand_num % (end - start + 1);
-}
-
-
-int set_rst_rand_key(int rnd_key)
-{
- g_iRandKey = rnd_key;
- return 0;
-}
-
-int set_rst_max_rnd_val(int max_rnd_val)
-{
- g_iMaxRandVal = max_rnd_val;
- return 0;
-}
-
-/*
- Ϊ�˼����ϰ�ϵͳ, ���ٱ�ϵͳ������RST��.
- IN ARG:
- sip, dip: network order;
-
- OUT ARG:
- ipid, win: host order;
-*/
-static void trick_algo_getrandval(int thread_id,unsigned sip,unsigned dip,unsigned short *ipid,unsigned short *win,u_char *ttl)
-{
- int val=randgroup[thread_id];
-
- if(val*g_iRandKey>g_iMaxRandVal)
- {
- randgroup[thread_id]=128;
- }
- else
- {
- randgroup[thread_id]++;
- }
- *win= (unsigned short)(val+dip%g_iRandKey);
- if(*win==0) *win=1;
- *ipid=(unsigned short)(g_iMaxRandVal-val*g_iRandKey+sip%(*win));
- *ttl=(u_char)(val % 200 + 48);
-
- return;
-}
-
-/* 2014-08-26 lijia add, ���ٱ�ϵͳ������RST��.*/
-static tcp_rst_finger_mark_t *make_tcp_rst_finger_mark(int thread_id, const raw_pkt_t *raw_pkt)
-{
- tcp_rst_finger_mark_t *rst_finger;
- const struct mesa_ip4_hdr *ip4_hdr;
-
- rst_finger = &g_tcp_rst_finger[thread_id];
-
- ip4_hdr = (const struct mesa_ip4_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, __ADDR_TYPE_IP_PAIR_V4);
- if(NULL == ip4_hdr){ /* ������ */
- rst_finger->ip_id_host_order = (unsigned short)MESA_rand();
- rst_finger->ip_ttl = (unsigned short)MESA_rand_range(48, 127);
- rst_finger->tcp_win_host_order = (unsigned short)MESA_rand_range(100, 1460);
- }else{
- trick_algo_getrandval(thread_id,
- ip4_hdr->ip_src.s_addr, /* 2015-10-27 lijia modify */
- ip4_hdr->ip_dst.s_addr, /* 2015-10-27 lijia modify */
- &rst_finger->ip_id_host_order,
- &rst_finger->tcp_win_host_order,
- &rst_finger->ip_ttl);
- }
-
- return rst_finger;
-}
-
-
-/*
- * Checksum stuff
- */
-#define SENDPACKET_CKSUM_CARRY(x) \
- (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
-
-
-/* 2012-04-10 LiJia add, ��ȡ����IPv4��ַ
-����:
- device: ��������
- ip_add: �洢IP��ַ��ָ�룬���Ϊ������.
-����ֵ:
- 0: ����
- -1:����
-*/
-int MESA_get_dev_ipv4(const char *device, int *ip_add)
-{
- 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, SIOCGIFADDR, &ifr) == -1)
- {
- //perror("Cann't get ip addr:");
- goto err_exit;
- }
-
- *ip_add = ((struct sockaddr_in*)&ifr.ifr_ifru.ifru_addr)->sin_addr.s_addr;
-
- close(fd);
-
- return 0;
-
-err_exit:
- close(fd);
- return -1;
-}
-
-/* 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 MESA_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 MESA_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(u_int16_t *addr, int len)
-{
- int sum;
- int nleft;
- u_int16_t ans;
- u_int16_t *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 sendpacket_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);
- }
-
- /*
- * Dug Song came up with this very cool checksuming implementation
- * eliminating the need for explicit psuedoheader use. Check it out.
- */
- switch (protocol)
- {
- /*
- * Style note: normally I don't advocate declaring variables inside
- * blocks of control, but it makes good sense here. -- MDS
- */
- case IPPROTO_TCP:
- {
- struct mesa_tcp_hdr *tcph_p =
- (struct mesa_tcp_hdr *)(buf + ip_hl);
-
-#if (STUPID_SOLARIS_CHECKSUM_BUG)
- tcph_p->th_sum = tcph_p->th_off << 2;
- return (1);
-#endif /* STUPID_SOLARIS_CHECKSUM_BUG */
-
- tcph_p->th_sum = 0;
- /* 2012-03-19 LiJia add, for IPv6 */
- if(is_ipv6)
- {
- sum = sendpacket_in_cksum((u_int16_t *)&ip6h_p->ip6_src, 32);
- }
- else
- {
- sum = sendpacket_in_cksum((u_int16_t *)&iph_p->ip_src, 8);
- }
- sum += ntohs(IPPROTO_TCP + len);
- sum += sendpacket_in_cksum((u_int16_t *)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;
- /* 2012-03-19 LiJia add, for IPv6 */
- if(is_ipv6)
- {
- sum = sendpacket_in_cksum((u_int16_t *)&ip6h_p->ip6_src, 32);
- }
- else
- {
- sum = sendpacket_in_cksum((u_int16_t *)&iph_p->ip_src, 8);
- }
- sum += ntohs(IPPROTO_UDP + len);
- sum += sendpacket_in_cksum((u_int16_t *)udph_p, len);
- udph_p->uh_sum = SENDPACKET_CKSUM_CARRY(sum);
- break;
- }
-
- case IPPROTO_IP: /* Dummy protocol for TCP. */
- {
- iph_p->ip_sum = 0;
- sum = sendpacket_in_cksum((u_int16_t *)iph_p, len);
- iph_p->ip_sum = SENDPACKET_CKSUM_CARRY(sum);
- break;
- }
-
- case IPPROTO_ICMP:
- {
- struct mesa_icmp_hdr *icmph_p =
- (struct mesa_icmp_hdr *)(buf + ip_hl);
-
- icmph_p->icmp_sum = 0;
- sum = sendpacket_in_cksum((u_short *)icmph_p, len);
- icmph_p->icmp_sum = SENDPACKET_CKSUM_CARRY(sum);
- break;
- }
-
- default:
- {
- return (-1);
- }
- }
- return (1);
-}
-
-int sendpacket_build_ipv4(u_int16_t carry_layer_len, u_int8_t tos, u_int16_t id, u_int16_t frag,
- u_int8_t ttl, u_int8_t prot, u_int32_t src, u_int32_t 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){
- /*
- * Unchecked runtime error for buf + IP_H + payload to be greater than
- * the allocated heap memory.
- */
- memcpy(buf + SENDPACKET_IP_H, payload, payload_s);
- }
- //memcpy((char *)buf, (char *)&ip_hdr, sizeof(ip_hdr));
-
- return (0);
-}
-
-
-/* TODO: ����չͷ����IPv6�� */
-int sendpacket_build_ipv6(u_int8_t traffic_class, u_int32_t flow_lable,
- u_int16_t len, u_int8_t next_header, u_int8_t 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)
- {
- /*
- * Unchecked runtime error for buf + IP_H + payload to be greater than
- * the allocated heap memory.
- */
- memcpy(buf + sizeof(struct mesa_ip6_hdr), payload, payload_s);
- }
-
- //memcpy(buf, &ip6_h, sizeof(struct mesa_ip6_hdr));
-
- return 0;
-}
-
-/* 2012-04-10 LiJia add, ���ڹ���ICMP-ECHO-REQUEST, ICMP-ECHO-REPLAY�� */
-int sendpacket_build_icmpv4_echo(u_int8_t type, u_int8_t code, u_int16_t sum,
- u_int16_t id, u_int16_t seq, u_int8_t *payload, u_int32_t payload_s, unsigned char *buf)
-{
- struct mesa_icmp_echo_hdr icmp_hdr;
-
- icmp_hdr.icmp_type = type;
- icmp_hdr.icmp_code = code;
- icmp_hdr.icmp_cksum = 0; /* checksum done in userland */
- icmp_hdr.icd_id = htons(id);
- icmp_hdr.icd_seq = htons(seq);
-
- if(payload && payload_s){
- /*
- * Unchecked runtime error for buf + IP_H + payload to be greater than
- * the allocated heap memory.
- */
- memcpy(buf + sizeof(struct mesa_icmp_echo_hdr), payload, payload_s);
- }
-
- memcpy(buf, &icmp_hdr, sizeof(struct mesa_icmp_echo_hdr));
-
- return 0;
-}
-
-
-int sendpacket_build_tcp(u_int16_t sp, u_int16_t dp, u_int32_t seq, u_int32_t ack,
- u_int8_t th_flags, u_int16_t win, u_int16_t 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){
- /*
- * Unchecked runtime error for buf + TCP_H + payload to be greater
- * than the allocated heap memory.
- */
- memcpy(buf + SENDPACKET_TCP_H, payload, payload_s);
- }
- //memcpy((char *)buf, (char *)&tcp_hdr, sizeof(tcp_hdr));
-
- return (0);
-}
-
-int sendpacket_build_tcp_with_option(u_int16_t sp, u_int16_t dp, u_int32_t seq,
- u_int32_t ack, u_int8_t control,u_int16_t win, u_int16_t urg,
- const char *option, int option_len, const char *payload, int payload_s,
- unsigned char *buf)
-{
- struct mesa_tcp_hdr tcp_hdr;
-
- if (!buf){
- return (-1);
- }
- if((option_len % 4) != 0){
- return (-2);
- }
-
- 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 = control; /* control flags */
- tcp_hdr.th_x2 = 0; /* UNUSED */
- tcp_hdr.th_off = 5 + option_len/4; /* 20 byte header + option_len */
- 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(option && option_len){
- memcpy(buf + SENDPACKET_TCP_H, option, option_len);
- }
-
- if (payload && payload_s){
- /*
- * Unchecked runtime error for buf + TCP_H + payload to be greater
- * than the allocated heap memory.
- */
- memcpy(buf + SENDPACKET_TCP_H + option_len, payload, payload_s);
- }
- memcpy((char *)buf, (char *)&tcp_hdr, sizeof(struct mesa_tcp_hdr));
- return (0);
-}
-
-int sendpacket_build_udp(u_int16_t sp, u_int16_t dp, const char *payload, int payload_s,
- unsigned char *buf)
-{
- struct mesa_udp_hdr udp_hdr;
-
- if (!buf)
- {
- return (-1);
- }
-
- udp_hdr.uh_sport = htons(sp); /* source port */
- udp_hdr.uh_dport = htons(dp); /* destination port */
- udp_hdr.uh_ulen = htons(SENDPACKET_UDP_H + payload_s); /* total length */
- udp_hdr.uh_sum = 0; /* checksum */
-
- if (payload && payload_s)
- {
- /*
- * Unchecked runtime error for buf + UDP_H + payload to be greater
- * than the allocated heap memory.
- */
- memcpy(buf + SENDPACKET_UDP_H, payload, payload_s);
- }
- memcpy(buf, &udp_hdr, sizeof(udp_hdr));
- return (1);
-}
-
-/* lijia add carry_layer_len args,
- ��Ƕ�ס�����ģʽ�¹������ݰ�, û��payload, ��ʵ�ʻ����ϲ�Э��, ��teredo, ��Э��ʱʹ��.
-*/
-int sendpacket_build_udp_dual_stack(u_int16_t sp, u_int16_t dp, const char *payload,
- int payload_s, int carry_layer_len, unsigned char *buf)
-{
- struct mesa_udp_hdr *udp_hdr;
-
- if (!buf){
- return (-1);
- }
-
- udp_hdr = (struct mesa_udp_hdr *)buf;
-
- udp_hdr->uh_sport = htons(sp); /* source port */
- udp_hdr->uh_dport = htons(dp); /* destination port */
- udp_hdr->uh_ulen = htons(SENDPACKET_UDP_H + carry_layer_len); /* total length */
- udp_hdr->uh_sum = 0; /* checksum */
-
- if (payload && payload_s){
- /*
- * Unchecked runtime error for buf + UDP_H + payload to be greater
- * than the allocated heap memory.
- */
- memcpy(buf + SENDPACKET_UDP_H, payload, payload_s);
- }
- //memcpy(buf, &udp_hdr, sizeof(udp_hdr));
- return (0);
-}
-
-int sendpacket_build_arp(u_short hrd, u_short pro, u_char hln, u_char pln, u_short op,
- u_char *sha, u_char *spa, u_char *tha, u_char *tpa,
- const u_char *payload, int payload_s, u_char *buf)
-{
- struct mesa_arp_hdr arp_hdr;
-
- if (!buf){
- return (-1);
- }
-
- arp_hdr.ar_hrd = htons(hrd); /* hardware address type */
- arp_hdr.ar_pro = htons(pro); /* protocol address type */
- arp_hdr.ar_hln = hln; /* hardware address length */
- arp_hdr.ar_pln = pln; /* protocol address length */
- arp_hdr.ar_op = htons(op); /* opcode command */
- memcpy(arp_hdr.ar_sha, sha, hln); /* sender hardware address */
- memcpy(arp_hdr.ar_spa, spa, pln); /* sender protocol (IP) address */
- memcpy(arp_hdr.ar_tha, tha, hln); /* target hardware address */
- memcpy(arp_hdr.ar_tpa, tpa, pln); /* target protocol (IP) address */
-
- if (payload && payload_s){
- /*
- * Unchecked runtime error for buf + LIBNET_ARP_H payload to be
- * greater than the allocated heap memory.
- */
- memcpy(buf + SENDPACKET_ARP_H, payload, payload_s);
- }
- memcpy(buf, &arp_hdr, sizeof(arp_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 sendpacket_build_ethernet(u_char *dst, u_char *src, u_short type,
- const u_char *payload, int payload_s, u_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)
- {
- /*
- * Unchecked runtime error for buf + ETH_H payload to be greater than
- * the allocated heap memory.
- */
- memcpy(buf + SENDPACKET_ETH_H, payload, payload_s);
- }
- memcpy(buf, ð_hdr, sizeof(eth_hdr));
- return (0);
-}
-
-#if 0
-static int __do_kill_tcp(sendpacketTool *pSend, int thread_num, char CtoS_dir, char StoC_dir,
- u_int32_t sip,ushort sid,ushort sport,u_int32_t sseq,u_int32_t sack,
- u_int32_t dip,ushort did,ushort dport,u_int32_t dseq,u_int32_t dack)
-{
- u_char sttl, dttl;
- ushort swin, dwin, nouse;
- int i, n_rst;
- int sendnum=0;
-#ifdef USE_TIME_TEST
- struct timeval tv;
- long begintime,endtime;
- gettimeofday(&tv, 0);
- begintime = tv.tv_sec* 1000*1000 + tv.tv_usec;
-
-#endif
-
- sip = htonl(sip);
-#if 1
- dip = htonl(dip);
-#else /* test */
- dip = htonl(0x0A00069A);
-#endif
- if((0 == rst_whom || 2 == rst_whom) && (0!=sseq)) { /* rst server */
- if(0 == sip || 0 == sport) return -1;
-
- //���ʹ�÷�������ôÿ����Ҫ���µõ�������
- if(g_UseSendpktCard)
- {
- pSend->send_buf=(char *)getbuffrompag(thread_num);
- }
-
- //if(0 != param->n_rst) n_rst = param->n_rst;
- //else n_rst=num_of_rst_tos_send;
- n_rst = num_of_rst_to_send;
- for(i = 0; i < n_rst; i ++)
- {
- getrandval(thread_num,sip,dip,&nouse,&swin,&sttl);
- if(-1 == sendpacket_build_ip(SENDPACKET_TCP_H, 0, sid, 0x4000, sttl,
- IPPROTO_TCP, sip, dip, NULL, 0, pSend->send_buf))
- {
- pSend->errflag=SEND_PACKET_IP_ERR;
- return -1;
- }
- if(-1 == sendpacket_build_tcp(sport,dport,sseq,sack,
- TH_RST|TH_ACK, swin, 0,NULL, 0,
- pSend->send_buf + SENDPACKET_IP_H))
- {
- pSend->errflag=SEND_PACKET_TCP_ERR;
- return -1;
- }
- if(-1 == sendpacket_do_checksum(pSend->send_buf,
- IPPROTO_TCP, SENDPACKET_TCP_H))
- {
- pSend->errflag=SEND_PACKET_CHECKSUM_ERR;
- return -1;
- }
- sendpacket_do_checksum(pSend->send_buf, IPPROTO_IP, SENDPACKET_IP_H);
- pSend->send_buf_location = 1;
- pSend->send_ptr = pSend->send_buf;
- sendnum=sendpacket_write_new(pSend, SENDPACKET_TCP_H + SENDPACKET_IP_H, CtoS_dir);
- if(sendnum==-1)
- {
- return -1;
- }
-
- g_OutInfo.rstnum[thread_num]++;
- sseq += 1460 * (i + 1);
- //���ʹ�����»�û�����
- if(g_UseSendpktCard)
- {
- if(i<n_rst-1)
- pSend->send_buf=(char *)regetbuffrompag(thread_num,pSend->send_buf,0,SENDPACKET_IP_H);
- }
- }
- //���ʹ�÷�������ôÿ����Ҫ���µõ�������
- if(g_UseSendpktCard)
- {
- pag_freesendbuf(thread_num);
- }
-
- }
- if ((0 == rst_whom || 1 == rst_whom)&&(0!=dseq)) { /* rst client */
- if(0 == dip || 0 == dport) return -1;
- //���ʹ�÷�������ôÿ����Ҫ���µõ�������
- if(g_UseSendpktCard)
- {
- pSend->send_buf=(char *)getbuffrompag(thread_num);
- }
-
-
- //if(0 != param->n_rst) n_rst = param->n_rst;
- //else n_rst=num_of_rst_toc_send;
- n_rst = num_of_rst_to_send;
- for(i = 0; i < n_rst; i ++) {
-
- getrandval(thread_num,sip,dip,&nouse,&dwin,&dttl);
-
- if(-1 == sendpacket_build_ip(SENDPACKET_TCP_H, 0, did, 0x4000, dttl,
- IPPROTO_TCP, dip, sip, NULL, 0, pSend->send_buf))
- {
- pSend->errflag=SEND_PACKET_IP_ERR;
- return -1;
- }
- if(-1 == sendpacket_build_tcp(dport,sport,dseq,dack,
- TH_RST|TH_ACK, dwin, 0, NULL, 0,
- pSend->send_buf + SENDPACKET_IP_H))
- {
- pSend->errflag=SEND_PACKET_TCP_ERR;
- return -1;
- }
- if(-1 == sendpacket_do_checksum(pSend->send_buf,
- IPPROTO_TCP, SENDPACKET_TCP_H))
- {
- pSend->errflag=SEND_PACKET_CHECKSUM_ERR;
- return -1;
- }
- sendpacket_do_checksum(pSend->send_buf, IPPROTO_IP, SENDPACKET_IP_H);
-
- pSend->send_buf_location = 1;
- pSend->send_ptr = pSend->send_buf;
- sendnum=sendpacket_write_new(pSend, SENDPACKET_TCP_H + SENDPACKET_IP_H, StoC_dir);
- if(sendnum==-1)
- {
- return -1;
- }
-
- g_OutInfo.rstnum[thread_num]++;
- dseq += 1460 * (i + 1);
- //���ʹ��,���»�û�����
- if(g_UseSendpktCard)
- {
- if(i<n_rst-1)
- pSend->send_buf=(char *)regetbuffrompag(thread_num,pSend->send_buf,0,SENDPACKET_IP_H);
- }
- }
- //���ʹ�÷�������ôÿ����Ҫ���µõ�������
- if(g_UseSendpktCard)
- {
- pag_freesendbuf(thread_num);
- }
- }
-
-#ifdef USE_TIME_TEST
- gettimeofday(&tv, 0);
- endtime = tv.tv_sec* 1000*1000 + tv.tv_usec;
- killcount++;
- killtime+=endtime-begintime;
- if(killcount%10000==0)
- {
- fprintf(stderr,"killcount=%lu,average usetime is %lu\n",killcount,(killtime-oldtime)/10000);
- MESA_runtime_log(RLOG_LV_INFO, "KILL TCP COUNT:", "killcount=%lu,average usetime is %lu\n",killcount,(killtime-oldtime)/10000);
- oldtime=killtime;
- }
-#endif
- return 0;
-}
-
-
-int MESA_kill_tcp(struct streaminfo *stream)
-{
- u_int32_t sip, sseq, sack, dip, dseq, dack, payload;
- u_int16_t sid, sport, did, dport;
- struct tcphdr *thdr;
- sendpacketTool *pTool;
- unsigned char C2S_dir, S2C_dir;
-
- thdr = (struct tcphdr*)((u_int8_t *)a_packet + (a_packet->ip_hl << 2) );
-
- payload = ntohs(a_packet->ip_len) - ((a_packet->ip_hl) << 2) - ((thdr->th_off) << 2);
- if(0 != (TH_SYN & thdr->th_flags))
- payload ++;
-
- sip = ntohl((a_packet->ip_src).s_addr);
- sseq = ntohl(thdr->th_seq) + payload;
- sack = ntohl(thdr->th_ack);
- dip = ntohl((a_packet->ip_dst).s_addr);
- dseq = ntohl(thdr->th_ack);
- dack = ntohl(thdr->th_seq) + payload;
-#if 1
- sid = a_packet->ip_id; /* sender host byte order */
- did = 128;
-#else /* test */
- sid = 0x1234;
- did = 0xdddd;
-#endif
-
- sport = ntohs(thdr->th_sport);
- dport = ntohs(thdr->th_dport);
-
- pTool = &g_SendPacketTools[stream->threadnum];
-
- if(1 == stream->curdir)
- {
- C2S_dir = stream->routedir;
- S2C_dir = stream->routedir ^ 0x80;
- }
- else
- {
- S2C_dir = stream->routedir;
- C2S_dir = stream->routedir ^ 0x80;
- }
-
- return __do_kill_tcp(pTool, stream->threadnum, (char)C2S_dir, (char)S2C_dir,
- sip, sid, sport, sseq, sack,
- dip, did, dport, dseq, dack);
-}
-#endif
-
-/*
- 1-�������а�ͷ�ij���, ����Ԥ���ռ�. ���㵽��ײ�Э��, �����MACҲ����MACͷ�ռ�;
- 2-�ݹ�����л�ȡEthernet����ص�Э������.
-*/
-static int calc_reserved_hdr_len(struct streaminfo *stream, int *net_layer_type)
-{
- int reserved_hdr_len = 0;
-
- if(NULL == stream){ /* �ݹ�����ս�����! */
- return 0;
- }
-
- if(is_proxy_stream(stream)){ /* �������ṹΪ����ṹ, ʵ�ʹ����ʱ���������� */
- reserved_hdr_len = 0;
- goto done;
- }
-
- switch(stream->addr.addrtype){
- case ADDR_TYPE_IPV4:
- /* 2015-12-30 lijia modify, IP�Ͷ˿�ͬʱ�洢�ڴ˽ṹ */
- if(STREAM_TYPE_TCP == stream->type){
- reserved_hdr_len = sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip4_hdr);
- }else if (STREAM_TYPE_UDP == stream->type){
- reserved_hdr_len = sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip4_hdr);
- }else{
- printf("addr type is tuple4v4, but stream type is not TCP or UDP!\n");
- sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: addr type is tuple4v4, but stream type is :%d, not TCP or UDP.\n", __FILE__, __LINE__, stream->type);
- return -1;
- //assert(0);
- }
- break;
-
- case ADDR_TYPE_IPV6:
- /* 2015-12-30 lijia modify, IP�Ͷ˿�ͬʱ�洢�ڴ˽ṹ */
- if(STREAM_TYPE_TCP == stream->type){
- reserved_hdr_len = sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip6_hdr);;
- }else if (STREAM_TYPE_UDP == stream->type){
- reserved_hdr_len = sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip6_hdr);;
- }else{
- printf("addr type is tuple4v6, but stream type is not TCP or UDP!\n");
- sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: addr type is tuple4v6, but stream type is :%d, not TCP or UDP.\n", __FILE__, __LINE__, stream->type);
- return -1;
- //assert(0);
- }
- break;
-
- case ADDR_TYPE_VLAN:
- reserved_hdr_len = VLAN_TAG_LEN;
- break;
-
- case ADDR_TYPE_MAC:
- reserved_hdr_len = sizeof(struct mesa_ethernet_hdr);
- break;
-
- case ADDR_TYPE_ARP:
- printf("Sendpacket use ARP!\n");
- sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Sendpacket use ARP.\n", __FILE__, __LINE__);
- return -1;
- //assert(0);
- break;
-
- case ADDR_TYPE_GRE:
- {
- struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream;
- reserved_hdr_len = calc_gre_hdr_len(
- (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr));
- }
- break;
-
- case ADDR_TYPE_MPLS:
- reserved_hdr_len = sizeof(struct mesa_mpls_hdr);
- break;
-
- case ADDR_TYPE_PPPOE_SES:
- reserved_hdr_len = sizeof(struct mesa_pppoe_session_hdr);
- break;
-
- case ADDR_TYPE_TCP:
- /* to do, ������ʹ�ѡ��İ�, ���Һ�ԭʼ����һ���Ļ�, ��ô����?
- ��Ԥ�����, Ȼ�����ʵ��ѡ���, ��memmove�ƶ��ѹ���ĸ���.
- */
- reserved_hdr_len = sizeof(struct mesa_tcp_hdr);
- break;
-
- case ADDR_TYPE_UDP:
- reserved_hdr_len = sizeof(struct mesa_udp_hdr);
- break;
-
- case ADDR_TYPE_L2TP:
- {
- struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream;
- reserved_hdr_len = calc_l2tp_hdr_len(
- (const struct l2tp_hdr_v2 *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr));
- }
- break;
-
- case __ADDR_TYPE_IP_PAIR_V4:
- /* to do, ��������ѡ��İ�, ��ô����? */
- reserved_hdr_len = sizeof(struct mesa_ip4_hdr);
- break;
-
- case __ADDR_TYPE_IP_PAIR_V6:
- /* to do, ��������ѡ��İ�, ��ô����? */
- reserved_hdr_len = sizeof(struct mesa_ip6_hdr);
- break;
-
- case ADDR_TYPE_PPP:
- assert(0); /* ���ٵ�����PPP��, ��L2TP, PPTP��Ϊһ�� */
- reserved_hdr_len = sizeof(struct mesa_ppp_hdr);
- break;
-
- case ADDR_TYPE_PPTP:
- {
- struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream;
- reserved_hdr_len = calc_gre_hdr_len(
- (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr));
- reserved_hdr_len += sizeof(struct mesa_ppp_hdr); /* plus ppp hdr */
- }
- break;
-
- default:
- /* to do */
- printf("calc_reserved_hdr_len(): Not support addrtype:%d\n", stream->addr.addrtype);
- reserved_hdr_len = -1;
- break;
- }
-
- if(reserved_hdr_len < 0){
- return -1;
- }
-
-#if 0 /* 2014-10-24 lijia modify, pag, ppf�Ȳ�����ʽ��IPv4��ʼ */
- if(stream->pfather && (ADDR_TYPE_MAC == stream->pfather->addr.addrtype)){
-#else
- if(CAP_LEVEL_MAC == g_packet_io_cap_level) {
- if(stream->pfather && (CAP_LEVEL_MAC == stream->pfather->addr.addrtype)){
- /* ��¼MAC��֮�ϵ�Э���ַ����, �������Ethernet->type�ֶ� */
- *net_layer_type = (int)stream->addr.addrtype;
- }
- }else{
- /* to do:
- ����������Զ�������ethernet��, ����������vlan�Ȳ���һ�Ҫ������ô��?
- */
- if(NULL == stream->pfather){
- if(g_packet_io_cap_level == stream->addr.addrtype){
- *net_layer_type = (int)stream->addr.addrtype;
- }
- if((CAP_LEVEL_IPV4 == g_packet_io_cap_level)
- && (ADDR_TYPE_IPV4 == stream->addr.addrtype)){
- *net_layer_type = CAP_LEVEL_IPV4;
- }
- }
- }
-#endif
-
-done:
- return reserved_hdr_len + calc_reserved_hdr_len(stream->pfather, net_layer_type);
-}
-
-static void set_build_layer_ipv4_args(int thread_num, unsigned char ip_ttl, unsigned short ip_id_host_order)
-{
- layer_args_t *thread_args;
- bulid_layer_ipv4_args_t *build_ip4_args;
-
- thread_args = &g_build_pkt_args[thread_num];
- build_ip4_args = &g_build_ipv4_args[thread_num];
-
- memset(build_ip4_args, 0, sizeof(bulid_layer_ipv4_args_t));
- build_ip4_args->ip_ttl = ip_ttl;
- build_ip4_args->ip_id_host_order = ip_id_host_order;
-
- thread_args->layer_args[__ADDR_TYPE_IP_PAIR_V4] = build_ip4_args;
-
- return;
-}
-
-static void set_build_layer_tcp_args( int thread_num,unsigned char tcp_flags,
- unsigned short tcp_win_host_order, unsigned int tcp_seq)
-{
- layer_args_t *thread_args;
- bulid_layer_tcp_args_t *build_tcp_args;
-
- thread_args = &g_build_pkt_args[thread_num];
- build_tcp_args = &g_build_tcp_args[thread_num];
-
- memset(build_tcp_args, 0, sizeof(bulid_layer_tcp_args_t));
- build_tcp_args->tcp_flags = tcp_flags;
- build_tcp_args->tcp_win_host_order = tcp_win_host_order;
- build_tcp_args->tcp_seq = tcp_seq;
-
- thread_args->layer_args[ADDR_TYPE_TCP] = build_tcp_args;
-
- return;
-}
-
-static inline void detach_build_layer_ipv4_args(int thread_num)
-{
- g_build_pkt_args[thread_num].layer_args[__ADDR_TYPE_IP_PAIR_V4] = NULL;
-}
-
-static inline void detach_build_layer_ipv6_args(int thread_num)
-{
- g_build_pkt_args[thread_num].layer_args[__ADDR_TYPE_IP_PAIR_V6] = NULL;
-}
-
-static inline void detach_build_layer_tcp_args(int thread_num)
-{
- g_build_pkt_args[thread_num].layer_args[ADDR_TYPE_TCP] = NULL;
-}
-
-#if 0
-static int __get_tcp_network_addr(struct streaminfo *stream, void *src_addr, void *dst_addr)
-{
- struct streaminfo *father = stream->pfather;
- int f_addr_type = __ADDR_TYPE_INIT;
-
- if(NULL == father){
- return f_addr_type;
- }
-
- if(ADDR_TYPE_IPV4 == father->addr.addrtype){
- struct stream_tuple4_v4 *t4 = father->addr.tuple4_v4;
- memcpy(src_addr, &t4->saddr, sizeof(int));
- memcpy(dst_addr, &t4->daddr, sizeof(int));
- f_addr_type = ADDR_TYPE_IPV4;
- }else if(__ADDR_TYPE_IP_PAIR_V6 == father->addr.addrtype){
- struct stream_tuple4_v6 *t6 = father->addr.tuple4_v6;
- memcpy(src_addr, &t6->saddr, IPV6_ADDR_LEN);
- memcpy(dst_addr, &t6->daddr, IPV6_ADDR_LEN);
- f_addr_type = __ADDR_TYPE_IP_PAIR_V6;
- }else{
- ;
- }
-
- return f_addr_type;
-}
-#endif
-
-static int build_net_layer_tcp(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_tcp_hdr *raw_tcp_hdr;
- struct tcpdetail *a_tcp = (struct tcpdetail *)(stream_pr->stream_public.pdetail);
- UINT16 tcp_win, tcp_flags;
- UINT32 tcp_seq;
- int tcp_data_len = a_tcp->datalen;
- bulid_layer_tcp_args_t *build_tcp_args;
-
-#if 0 /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ�� */
- raw_tcp_hdr = (struct mesa_tcp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
-#else
- raw_tcp_hdr = (struct mesa_tcp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + stream_pr->offset_to_ip_hdr + (char *)raw_pkt->raw_pkt_data);
-#endif
-
- build_tcp_args = (bulid_layer_tcp_args_t *)g_build_pkt_args[stream_pr->stream_public.threadnum].layer_args[ADDR_TYPE_TCP];
-
- if(raw_tcp_hdr->th_flags & TH_SYN){
- tcp_data_len++;
- }
-
- if(NULL == build_tcp_args){
- tcp_flags = TH_ACK;
- tcp_win = (UINT16)MESA_rand_range(1000, 1460);
- tcp_seq = (UINT32)MESA_rand();
- }else{
- tcp_flags = build_tcp_args->tcp_flags;
- tcp_win = build_tcp_args->tcp_win_host_order;
- if(0 == build_tcp_args->tcp_seq){
- if(reverse){
- tcp_seq = ntohl(raw_tcp_hdr->th_ack);
- }else{
- tcp_seq = ntohl(raw_tcp_hdr->th_seq)+tcp_data_len;
- }
- }else{
- tcp_seq = build_tcp_args->tcp_seq;
- }
- }
-
- if(reverse){
- sendpacket_build_tcp(ntohs(raw_tcp_hdr->th_dport),
- ntohs(raw_tcp_hdr->th_sport),
- tcp_seq,
- ntohl(raw_tcp_hdr->th_seq)+tcp_data_len,
- tcp_flags,
- tcp_win,
- 0,
- NULL,
- 0,
- (unsigned char *)buf);
- }else{
- sendpacket_build_tcp(ntohs(raw_tcp_hdr->th_sport),
- ntohs(raw_tcp_hdr->th_dport),
- tcp_seq,
- ntohl(raw_tcp_hdr->th_ack),
- tcp_flags,
- tcp_win,
- 0,
- NULL,
- 0,
- (unsigned char *)buf);
- }
-
- return sizeof(struct mesa_tcp_hdr);
-}
-
-static int build_net_layer_udp(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_udp_hdr *raw_udp_hdr;
-
-#if 0
- raw_udp_hdr = (struct mesa_udp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
-#else
- raw_udp_hdr = (struct mesa_udp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + stream_pr->offset_to_ip_hdr + (char *)raw_pkt->raw_pkt_data);
-#endif
-
- if(reverse){
- sendpacket_build_udp_dual_stack(ntohs(raw_udp_hdr->uh_dport),
- ntohs(raw_udp_hdr->uh_sport),
- NULL,
- 0,
- carry_layer_len,
- buf);
- }else{
- sendpacket_build_udp_dual_stack(ntohs(raw_udp_hdr->uh_sport),
- ntohs(raw_udp_hdr->uh_dport),
- NULL,
- 0,
- carry_layer_len,
- buf);
- }
-
- return sizeof(struct mesa_udp_hdr);
-}
-
-
-static int build_net_layer_ipv4(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_ip4_hdr *raw_ip4_hdr;
- UINT16 ip_id;
- UINT8 ip_ttl;
- bulid_layer_ipv4_args_t *build_ip4_args;
-
- raw_ip4_hdr = (struct mesa_ip4_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
- build_ip4_args = (bulid_layer_ipv4_args_t *)g_build_pkt_args[stream_pr->stream_public.threadnum].layer_args[__ADDR_TYPE_IP_PAIR_V4];
-
- if(NULL == build_ip4_args){
- ip_id = (UINT16)MESA_rand();
- ip_ttl = (UINT8)MESA_rand_range(48, 127);
- }else{
- ip_id = build_ip4_args->ip_id_host_order;
- ip_ttl = build_ip4_args->ip_ttl;
- }
-
- if(reverse){
- sendpacket_build_ipv4(carry_layer_len,
- 0,
- ip_id,
- IP_DF,
- ip_ttl,
- net_layer_to_ipv4_protocol(carry_layer_type),
- raw_ip4_hdr->ip_dst.s_addr,
- raw_ip4_hdr->ip_src.s_addr,
- NULL,
- 0,
- (unsigned char *)buf);
- }else{
- sendpacket_build_ipv4(carry_layer_len,
- 0,
- ip_id,
- IP_DF,
- ip_ttl,
- net_layer_to_ipv4_protocol(carry_layer_type),
- raw_ip4_hdr->ip_src.s_addr,
- raw_ip4_hdr->ip_dst.s_addr,
- NULL,
- 0,
- (unsigned char *)buf);
- }
-
- sendpacket_do_checksum(buf, IPPROTO_IP, sizeof(struct mesa_ip4_hdr));
-
- return sizeof(struct mesa_ip4_hdr);
-}
-
-static int build_net_layer_ipv6(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_ip6_hdr *raw_ip6_hdr;
- UINT8 hop = (UINT8)MESA_rand_range(64, 128);
-
- if(0 == g_packet_io_ipv6_switch){
- printf("IPv6 module is not support! Please set 'IPv6_module_enable=1' in main.conf.\n");
- return -1;
- }
-
- raw_ip6_hdr = (struct mesa_ip6_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
-
- if(reverse){
- sendpacket_build_ipv6(0,
- 0,
- carry_layer_len,
- net_layer_to_ipv6_protocol(carry_layer_type),
- hop,
- &raw_ip6_hdr->ip6_dst,
- &raw_ip6_hdr->ip6_src,
- NULL,
- 0,
- (unsigned char *)buf);
- }else{
- sendpacket_build_ipv6(0,
- 0,
- carry_layer_len,
- net_layer_to_ipv6_protocol(carry_layer_type),
- hop,
- &raw_ip6_hdr->ip6_src,
- &raw_ip6_hdr->ip6_dst,
- NULL,
- 0,
- (unsigned char *)buf);
- }
-
- return sizeof(struct mesa_ip6_hdr);
-}
-
-static int build_net_layer_pppoe_ses(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_pppoe_session_hdr *raw_hdr;
- struct mesa_pppoe_session_hdr *send_hdr = (struct mesa_pppoe_session_hdr *)buf;
-
- raw_hdr = (struct mesa_pppoe_session_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
-
- /* PPPOE������, ��ԭʼ����copy���� */
- (void)reverse;
- memcpy(send_hdr, raw_hdr, sizeof(struct mesa_pppoe_session_hdr));
-
- /* lijia comment:
- �˴�Ϊ��Ҫ��sizeof(send_hdr->ppp_protocol)?
- ��ΪPPPOE_SES��ͷ�����Dz���PPPЭ�������ֶε�, ��Ϊ�˷��㴦��, ������2��1��.
- */
- send_hdr->len = htons(carry_layer_len + sizeof(send_hdr->ppp_protocol));
-
- return sizeof(struct mesa_pppoe_session_hdr);
-}
-
-static int build_net_layer_vlan(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_vlan_hdr *raw_hdr;
- struct mesa_vlan_hdr *send_hdr = (struct mesa_vlan_hdr *)buf;
-
- raw_hdr = (struct mesa_vlan_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
-
- /* VLAN������, ��ԭʼ����copy���� */
- (void)reverse;
- memcpy(send_hdr, raw_hdr, sizeof(struct mesa_vlan_hdr));
-
- return sizeof(struct mesa_vlan_hdr);
-}
-
-static int build_net_layer_gerv0_exthdr(const struct mesa_gre_hdr *parsed_hdr, struct mesa_gre_hdr *send_hdr)
-{
- const struct mesa_gre_extend_hdr *parsed_ext_hdr = (const struct mesa_gre_extend_hdr *)&parsed_hdr->gre_extend;
- char *send_ext_value = (char *)&send_hdr->gre_extend;
-
-
- if(parsed_hdr->gre_base.checksum_flag != 0){
- memcpy(send_ext_value, &parsed_ext_hdr->checksum, sizeof(short));
- send_ext_value += sizeof(short);
- memcpy(send_ext_value, &parsed_ext_hdr->offset, sizeof(short));
- send_ext_value += sizeof(short);
- }
-
- if(parsed_hdr->gre_base.key_flag != 0){
- memcpy(send_ext_value, &parsed_ext_hdr->key, sizeof(int));
- send_ext_value += sizeof(int);
- }
-
- if(parsed_hdr->gre_base.seq_flag != 0){
- unsigned tmp_int = htons(ntohs(parsed_ext_hdr->seq_num) + 1); /* seq + 1 */
- memcpy(send_ext_value, &tmp_int, sizeof(int));
- send_ext_value += sizeof(int);
- }
-
- return 0;
-}
-
-static int build_net_layer_gerv1_exthdr(const struct mesa_gre_hdr *parsed_hdr,
- struct mesa_gre_hdr *send_hdr, int carry_layer_len, UINT16 send_call_id, int reverse)
-{
- const struct mesa_gre_base_hdr_v1*parsed_base_hdr = (const struct mesa_gre_base_hdr_v1*)&parsed_hdr->gre_base;
- const struct mesa_gre_extend_hdr *parsed_ext_hdr = (const struct mesa_gre_extend_hdr *)&parsed_hdr->gre_extend;
- char *send_ext_value = (char *)&(send_hdr->gre_extend);
- struct mesa_gre_base_hdr_v1 *send_grev1_hdr = (struct mesa_gre_base_hdr_v1 *)send_hdr;
-
- unsigned short payload_len = (unsigned short)carry_layer_len;
- payload_len = htons(payload_len);
-
- memcpy(send_ext_value, &payload_len, sizeof(short)); /* GREv1 �ض���length�ֶ� */
- send_ext_value += sizeof(short);
-
- memcpy(send_ext_value, &send_call_id, sizeof(short)); /* GREv1 �ض���callid�ֶ� */
- send_ext_value += sizeof(short);
-
- if(0 == reverse){
- if(parsed_base_hdr->seq_flag != 0){
- unsigned tmp_int = htonl(ntohl(parsed_ext_hdr->seq_num) + 1); /* seq + 1 */
- memcpy(send_ext_value, &tmp_int, sizeof(int));
- send_ext_value += sizeof(int);
- send_grev1_hdr->seq_flag = 1;
- }else{
- send_grev1_hdr->seq_flag = 0;
- }
-
- if(parsed_base_hdr->ack_flag != 0){
- memcpy(send_ext_value, &parsed_ext_hdr->ack_num, sizeof(int));
- send_ext_value += sizeof(int);
- send_grev1_hdr->ack_flag = 1;
- }else{
- send_grev1_hdr->ack_flag = 0;
- }
- }else{
- if(parsed_base_hdr->ack_flag != 0){
- unsigned tmp_int = htonl(ntohl(parsed_ext_hdr->ack_num) + 1); /* seq = opposite_ack + 1 */
- memcpy(send_ext_value, &tmp_int, sizeof(int));
- send_ext_value += sizeof(int);
- send_grev1_hdr->seq_flag = 1;
- }else{
- send_grev1_hdr->seq_flag = 0;
- }
-
- if(parsed_base_hdr->seq_flag != 0){
- memcpy(send_ext_value, &parsed_ext_hdr->seq_num, sizeof(int)); /* ack = opposite_seq */
- send_ext_value += sizeof(int);
- send_grev1_hdr->ack_flag = 1;
- }else{
- send_grev1_hdr->ack_flag = 0;
- }
- }
-
- return 0;
-}
-
-static int build_net_layer_gre(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- const struct mesa_gre_hdr *raw_hdr;
- struct mesa_gre_hdr stack_hdr;
- struct mesa_gre_hdr *send_hdr = (struct mesa_gre_hdr *)buf;
- int gre_hdr_len, ret;
- const struct layer_addr_pptp *raw_pptp_addr = stream_pr->stream_public.addr.pptp;
-#if 0
- /* NOTE: BUGFIX, ��ǰ����curdir���ܲ�û������, ��Ϊֻ��TCP��������curdir, ���Բ���ȡ��������curdirֵ */
- UCHAR curdir = stream_pr->stream_public.curdir;
-#endif
- UINT16 send_call_id;
-
- raw_hdr = (const struct mesa_gre_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
- gre_hdr_len = set_gre_hdr(&stack_hdr, (const void *)raw_hdr);
- if(gre_hdr_len < 0){
- return -1;
- }
-
- if((reverse != 0)
- && ((0 == raw_pptp_addr->C2S_call_id) || (0 == raw_pptp_addr->S2C_call_id))){
- /* ������һ������û�л�ȡ��callid, ����������� */
- sapp_runtime_log(20, "in gre layer, send dir is reverse, but haven't get opposite single stream info!\n");
- return -1;
- }
-
- if(0 == reverse){
- if(stack_hdr.gre_extend.call_id == raw_pptp_addr->C2S_call_id){
- /* ͬ��, �͵�ǰ����һ�� */
- send_call_id = raw_pptp_addr->C2S_call_id;
- }else{
- send_call_id = raw_pptp_addr->S2C_call_id;
- }
- }else{
- /* ����, ʹ�öԶ˵�callid */
- if(stack_hdr.gre_extend.call_id == raw_pptp_addr->C2S_call_id){
- send_call_id = raw_pptp_addr->S2C_call_id;
- }else{
- send_call_id = raw_pptp_addr->C2S_call_id;
- }
- }
-
- memcpy(&send_hdr->gre_base, &raw_hdr->gre_base, sizeof(struct mesa_gre_base_hdr_v0));
-
- if(0 == stack_hdr.gre_base.version){
- ret = build_net_layer_gerv0_exthdr(&stack_hdr, send_hdr);
- }else if(1 == stack_hdr.gre_base.version){
- ret = build_net_layer_gerv1_exthdr(&stack_hdr, send_hdr, carry_layer_len, send_call_id, reverse);
- }else{
- return -1;
- }
-
- if(ret < 0){
- return -1;
- }
-
- return gre_hdr_len;
-}
-
-static int build_net_layer_mpls(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_mpls_hdr *raw_hdr;
-
- raw_hdr = (struct mesa_mpls_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
-
- /* MPLS������, ��ԭʼ����copy���� */
- (void)reverse;
- memcpy(buf, raw_hdr, sizeof(struct mesa_mpls_hdr));
-
- return sizeof(struct mesa_mpls_hdr);
-}
-
-static void checksum_for_carry_layer(unsigned char *buf, int this_layer_type, int carry_layer_type, int payload_len)
-{
- if((ADDR_TYPE_TCP != carry_layer_type) && (ADDR_TYPE_UDP != carry_layer_type)){
- return;
- }
-
- if(__ADDR_TYPE_IP_PAIR_V4 == this_layer_type){
- sendpacket_do_checksum(buf, net_layer_to_ipv4_protocol(carry_layer_type), payload_len);
- }else if(__ADDR_TYPE_IP_PAIR_V6 == this_layer_type){
- sendpacket_do_checksum(buf, net_layer_to_ipv6_protocol(carry_layer_type), payload_len);
- }else{
- return;
- }
-}
-
-static int build_net_layer_ppp(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- struct mesa_ppp_hdr *raw_ppp_hdr;
-
- raw_ppp_hdr = (struct mesa_ppp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
-
- /* PPP������, ��ԭʼ����copy���� */
- (void)reverse;
- memcpy(buf, raw_ppp_hdr, sizeof(struct mesa_ppp_hdr));
-
- return sizeof(struct mesa_ppp_hdr);
-}
-
-static int build_net_layer_l2tp(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt, int l2tp_raw_hdr_len)
-{
- const struct l2tp_hdr_v2 *raw_hdr;
- const char *raw_hdr_ptr;
- unsigned char *send_ptr = buf;
- unsigned short int16_tmp;
-
- if(reverse != 0){
- /* TODO:
- L2TP��c2s��s2c����TUNNEL-ID��һ��, Ŀǰû���γ�L2TP��, ��������һ���������Ϣ ,
- ����, ��ʱֻ�ܵ���KILL.
- */
- return -1;
- }
-
- raw_hdr = (const struct l2tp_hdr_v2 *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data);
- raw_hdr_ptr = (const char *)raw_hdr;
- memcpy(send_ptr, raw_hdr, sizeof(struct l2tp_hdr_v2));
- send_ptr += sizeof(struct l2tp_hdr_v2);
- raw_hdr_ptr += sizeof(struct l2tp_hdr_v2);
-
- if(raw_hdr->length_present){
- int16_tmp = carry_layer_len + l2tp_raw_hdr_len;
- int16_tmp = ntohs(int16_tmp);
- memcpy(send_ptr, &int16_tmp, sizeof(short));
- send_ptr += sizeof(short);
- raw_hdr_ptr += sizeof(short);
- }
-
- memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte tunnel id */
- send_ptr += sizeof(short);
- raw_hdr_ptr += sizeof(short);
-
- memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte session id */
- send_ptr += sizeof(short);
- raw_hdr_ptr += sizeof(short);
-
- if(raw_hdr->seq_present){
- memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte Ns */
- send_ptr += sizeof(short);
- raw_hdr_ptr += sizeof(short);
-
- memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte Nr */
- send_ptr += sizeof(short);
- raw_hdr_ptr += sizeof(short);
- }
-
- if(raw_hdr->offset_present){
- int16_tmp = ntohs(*(unsigned short *)raw_hdr_ptr); /* offset size */
- memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte offset */
- send_ptr += sizeof(short);
- raw_hdr_ptr += sizeof(short);
-
- memcpy(send_ptr, raw_hdr_ptr, int16_tmp);
- send_ptr += int16_tmp;
- raw_hdr_ptr += int16_tmp;
- }
-
- return l2tp_raw_hdr_len;
-}
-
-/*
- buf: ִ��Ӧ�ò㸺�ص�ַ, skip hdr.
- reverse: �����з����Եĵ�ַ, �跴��.
-*/
-static int build_net_layer_pkt(struct streaminfo_private *stream_pr, int carry_layer_type,
- int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt)
-{
- int this_layer_len = 0, ret;
- int transport_layer_len;
- struct streaminfo *stream;
-
- if(NULL == stream_pr){
- return carry_layer_len;
- }
-
- stream = &stream_pr->stream_public;
-
- if(is_proxy_stream(stream)){ /* �������ṹΪ����ṹ, ʵ�ʵİ������ڴ˲�, �����ʱ���������� */
- this_layer_len = 0;
- goto done;
- }
-
- switch(stream->addr.addrtype){
- case ADDR_TYPE_IPV4:
- /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, �ȹ���TCP/UDP�� */
- if(STREAM_TYPE_TCP == stream->type){
- transport_layer_len = sizeof(struct mesa_tcp_hdr);
- buf -= sizeof(struct mesa_tcp_hdr);
- build_net_layer_tcp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_TCP;
- }else{
- transport_layer_len = sizeof(struct mesa_udp_hdr);
- buf -= sizeof(struct mesa_udp_hdr);
- build_net_layer_udp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_UDP;
- }
-
- /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, ��������IPv4�� */
- this_layer_len += sizeof(struct mesa_ip4_hdr) + transport_layer_len;
- buf -= sizeof(struct mesa_ip4_hdr);
- build_net_layer_ipv4(stream_pr, carry_layer_type, carry_layer_len + transport_layer_len, buf, reverse, raw_pkt);
-
- /* TCP��У�����ҪIP��ַ��Ϣ, ����Ҫ�ڹ�����IP����Ϣ��, �ټ���checksum */
- checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V4, carry_layer_type, carry_layer_len+transport_layer_len);
- carry_layer_type = __ADDR_TYPE_IP_PAIR_V4;
-
- break;
-
- case ADDR_TYPE_IPV6:
- /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, �ȹ���TCP/UDP�� */
- if(STREAM_TYPE_TCP == stream->type){
- transport_layer_len = sizeof(struct mesa_tcp_hdr);
- buf -= sizeof(struct mesa_tcp_hdr);
- build_net_layer_tcp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_TCP;
- }else{
- transport_layer_len = sizeof(struct mesa_udp_hdr);
- buf -= sizeof(struct mesa_udp_hdr);
- build_net_layer_udp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_UDP;
- }
-
- /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, ��������IPv6�� */
- this_layer_len += sizeof(struct mesa_ip6_hdr) + transport_layer_len;
- buf -= sizeof(struct mesa_ip6_hdr);
- build_net_layer_ipv6(stream_pr, carry_layer_type, carry_layer_len + transport_layer_len, buf, reverse, raw_pkt);
-
- /* TCP��У�����ҪIP��ַ��Ϣ, ����Ҫ�ڹ�����IP����Ϣ��, �ټ���checksum */
- checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V6, carry_layer_type, carry_layer_len+transport_layer_len);
- carry_layer_type = __ADDR_TYPE_IP_PAIR_V6;
- break;
-
- case __ADDR_TYPE_IP_PAIR_V4:
- /* to do, ��������ѡ��İ�, ��ô����? */
- this_layer_len = sizeof(struct mesa_ip4_hdr);
- buf -= sizeof(struct mesa_ip4_hdr);
- build_net_layer_ipv4(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
-
- /* TCP��У�����ҪIP��ַ��Ϣ, ����Ҫ�ڹ�����IP����Ϣ��, �ټ���checksum */
- checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V4, carry_layer_type, carry_layer_len);
- carry_layer_type = __ADDR_TYPE_IP_PAIR_V4;
- break;
-
- case __ADDR_TYPE_IP_PAIR_V6:
- this_layer_len = sizeof(struct mesa_ip6_hdr);
- buf -= sizeof(struct mesa_ip6_hdr);
- build_net_layer_ipv6(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V6, carry_layer_type, carry_layer_len);
- carry_layer_type = __ADDR_TYPE_IP_PAIR_V6;
- break;
-
- case ADDR_TYPE_VLAN:
- this_layer_len = VLAN_TAG_LEN;
- buf -= sizeof(struct mesa_vlan_hdr);
- build_net_layer_vlan(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_VLAN;
- break;
-
- case ADDR_TYPE_MAC:
- this_layer_len = 0;
- //this_layer_len = build_net_layer_ethernet(stream, payload, payload_len, buf, reverse, net_layer);
- //net_layer = NET_LAYER_ETHERNET;
- /* ����ģʽ��, ����ֱ�ӿ�ϵͳsendto����, ����MAC��ַ����buildϵ�к���������, ��dl_io����� */
- return carry_layer_len;
- break;
-
- /* TODO: GRE v1��callid, �ֱ�洢��C2S, S2C������������ݰ�, ����˫��RST��Ҫ��¼��һ�����ֵ */
- case ADDR_TYPE_GRE:
- this_layer_len = calc_gre_hdr_len(
- (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr));
- buf -= this_layer_len;
- ret = build_net_layer_gre(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- if(ret < 0){
- return -1;
- }
- carry_layer_type = ADDR_TYPE_GRE;
- break;
-
- case ADDR_TYPE_MPLS:
- this_layer_len = sizeof(struct mesa_mpls_hdr);
- buf -= sizeof(struct mesa_mpls_hdr);
- build_net_layer_mpls(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_MPLS;
- break;
-
- case ADDR_TYPE_PPPOE_SES:
- this_layer_len = sizeof(struct mesa_pppoe_session_hdr);
- buf -= sizeof(struct mesa_pppoe_session_hdr);
- build_net_layer_pppoe_ses(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_PPPOE_SES;
- break;
-
- case ADDR_TYPE_TCP:
- /* to do, ��������ѡ��İ�, ��ô����? */
- this_layer_len = sizeof(struct mesa_tcp_hdr);
- buf -= sizeof(struct mesa_tcp_hdr);
- build_net_layer_tcp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_TCP;
- break;
-
- case ADDR_TYPE_UDP:
- this_layer_len = sizeof(struct mesa_udp_hdr);
- buf -= sizeof(struct mesa_udp_hdr);
- build_net_layer_udp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_UDP;
- break;
-
- case ADDR_TYPE_L2TP:
- this_layer_len = calc_l2tp_hdr_len(
- (const struct l2tp_hdr_v2 *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr));
- if(this_layer_len < 0){
- return -1;
- }
- buf -= this_layer_len;
- ret = build_net_layer_l2tp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt, this_layer_len);
- if(ret < 0){
- return -1;
- }
- carry_layer_type = ADDR_TYPE_L2TP;
- break;
-
- case ADDR_TYPE_PPP:
- assert(0);
- this_layer_len = sizeof(struct mesa_ppp_hdr);
- buf -= sizeof(struct mesa_ppp_hdr);
- build_net_layer_ppp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
- carry_layer_type = ADDR_TYPE_PPP;
- break;
-
- case ADDR_TYPE_PPTP:
- {
- int gre_layer_len;
- buf -= sizeof(struct mesa_ppp_hdr);
- build_net_layer_ppp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt);
-
- gre_layer_len = calc_gre_hdr_len(
- (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr));
-
- /* ֱ��copy pppͷ������ */
- memcpy(buf, (char *)raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr + gre_layer_len, sizeof(struct mesa_ppp_hdr));
-
- buf -= gre_layer_len;
- ret = build_net_layer_gre(stream_pr, ADDR_TYPE_PPP, carry_layer_len, buf, reverse, raw_pkt);
- if(ret < 0){
- return -1;
- }
- carry_layer_type = ADDR_TYPE_GRE;
- this_layer_len = gre_layer_len + sizeof(struct mesa_ppp_hdr);
- }
- break;
-
- default:
- printf("build_net_layer_pkt(): unsupport protocol:%d! TODO!\n", stream->addr.addrtype);
- goto err;
- break;
- }
-
-done:
- return build_net_layer_pkt((struct streaminfo_private *)stream->pfather,carry_layer_type,
- this_layer_len+carry_layer_len,
- buf, reverse, raw_pkt);
-
-err:
- return -1;
-}
-
-
-static int __do_kill_tcp(struct streaminfo *stream, const void *ext_raw_pkt, int kill_num,
- char *feedback_buf, int *feedback_buf_len)
-{
- int i, ret = -1, reserved_hdr_len, send_len = 0;
- MESA_send_handle *send_handle;
- int thread_num = stream->threadnum;
- int low_net_layer_type = -1;
- tcp_rst_finger_mark_t *tcp_rst_finger;
- const raw_pkt_t *raw_pkt = NULL;
- struct streaminfo_private *stream_pr;
-
- (void)ext_raw_pkt;
-
- if(NULL == stream){
- return -1;
- }
-
- stream_pr = (struct streaminfo_private *)stream;
- send_handle = &g_send_handle[thread_num];
-
- /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ(����֮ǰpappƽ̨), ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */
- raw_pkt = (const raw_pkt_t *)stream_pr->raw_pkt;
-
- if((NULL == raw_pkt) || (RAW_PKT_MAGIC_NUM != raw_pkt->magic_num)){
- return -1;
- }
-
- reserved_hdr_len = calc_reserved_hdr_len(stream, &low_net_layer_type);
- if((reserved_hdr_len < 0) || (-1 == low_net_layer_type)){
- sapp_runtime_log(RLOG_LV_INFO, "%s:%d: MESA_kill_tcp() calc_reserved_hdr_len error !", __FILE__, __LINE__);
- ret = -1;
- goto fun_exit;
- }
-
- tcp_rst_finger = make_tcp_rst_finger_mark(thread_num, (const raw_pkt_t *)raw_pkt);
- set_build_layer_ipv4_args(thread_num, tcp_rst_finger->ip_ttl, tcp_rst_finger->ip_id_host_order);
- set_build_layer_tcp_args(thread_num, TH_RST|TH_ACK, tcp_rst_finger->tcp_win_host_order, 0);
-
- for(i = 0; i < kill_num; i++){
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
-
- send_len = build_net_layer_pkt(stream_pr, ADDR_TYPE_TCP, 0, send_handle->send_buf + reserved_hdr_len, 0, raw_pkt);
- if(send_len < 0){
- ret = -1;
- goto fun_exit;
- }
- ret = packet_io_send(send_handle, reserved_hdr_len, SEND_TYPE_LINK_INJECT,
- low_net_layer_type, stream->routedir, thread_num,
- feedback_buf, feedback_buf_len);
- if(ret < 0){
- send_handle->tot_send_err++;
- }else{
- send_handle->tot_send_pkt++;
- send_handle->tot_send_byte += send_len;
- }
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
-
- g_SysInputInfo[thread_num][SEND_TCP_RST]++;
- g_SysInputInfo[thread_num][SEND_TCP_RST_LEN]+=send_len;
-
- /* ����ģʽ��, �����������һ��, �ܼ�����,
- �������ȷ�C2S���Ρ��ٷ�S2C����,
- ��ֹ��RST����ʱ����, ��һ���ٳ�û�а�;
- */
-#if 0
- }
-
- for(i = 0; i < KILL_TCP_RST_NUM; i++){
-#endif
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
- send_len = build_net_layer_pkt(stream_pr, ADDR_TYPE_TCP, 0, send_handle->send_buf + reserved_hdr_len, 1, raw_pkt);
- if(send_len < 0){
- ret = -1;
- goto fun_exit;
- break;
- }
- ret = packet_io_send(send_handle, reserved_hdr_len, SEND_TYPE_LINK_INJECT,
- low_net_layer_type, stream->routedir ^ 1, thread_num,
- feedback_buf, feedback_buf_len);
- if(ret < 0){
- send_handle->tot_send_err++;
- }else{
- send_handle->tot_send_pkt++;
- send_handle->tot_send_byte += send_len;
- }
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
- g_SysInputInfo[thread_num][SEND_TCP_RST]++;
- g_SysInputInfo[thread_num][SEND_TCP_RST_LEN]+=send_len;
- }
-
-fun_exit:
-
- detach_build_layer_ipv4_args(thread_num);
- detach_build_layer_tcp_args(thread_num);
-
- stream_pr->stream_killed_flag = 1;
-
- return ret;
-}
-
-
-
-/*
- LiJia note, to do:
- �������������, 1,2,3,4,x,6, ��5��������, ��6����������,
- �����6��������������Ϣ, ��Ҫkill_tcp,
- ����5��������ʱ, streaminfo��洢�Ķ��ǵ�5��������Ϣ,
- Ȼ���ٴ��������е�6����������, ��ʱ����kill_tcp, ��ز����Dz��Ե�,
- ʵ�ʵ�seq��ackʹ�õ��ǵ�5������!
- Ӧ��ʹ��buf_unorder�е�seq��ack, �����ǵ�ǰ����ԭʼ��.
-*/
-int MESA_kill_tcp(struct streaminfo *stream, const void *ext_raw_pkt)
-{
- /* �ⲿ����, ��һ��FD, ����KILL_TCP_RST_NUM��. */
- return __do_kill_tcp(stream, ext_raw_pkt, KILL_TCP_RST_NUM, (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-}
-
-int MESA_kill_tcp_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len)
-{
- if((NULL == feedback_buf) || (NULL == feedback_buf_len)){
- return -2;
- }
- if(*feedback_buf_len <= 0){
- return -2;
- }
- return __do_kill_tcp(stream, raw_pkt, KILL_TCP_RST_NUM, feedback_buf, feedback_buf_len);
-}
-
-/* 2016-06-15 lijia add */
-int MESA_kill_tcp_remedy(struct streaminfo *stream, const void *ext_raw_pkt)
-{
- /* FD����, ֻ����1��. */
- return __do_kill_tcp(stream, ext_raw_pkt, 1, (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-}
-
-static int __do_kill_tcp_synack(struct streaminfo *stream, const void *ext_raw_pkt,
- char *feedback_buf, int *feedback_buf_len)
-{
- int i, ret, reserved_hdr_len, send_len = 0;
- MESA_send_handle *send_handle;
- int thread_num = stream->threadnum;
- int low_net_layer_type;
- tcp_rst_finger_mark_t *tcp_rst_finger;
- const raw_pkt_t *raw_pkt = NULL;
- struct streaminfo_private *stream_pr;
-
- (void)ext_raw_pkt;
-
- if(NULL == stream){
- return -1;
- }
-
- stream_pr = (struct streaminfo_private *)stream;
- send_handle = &g_send_handle[thread_num];
- raw_pkt = (const raw_pkt_t *)stream_pr->raw_pkt;
- if((NULL == raw_pkt) || (RAW_PKT_MAGIC_NUM != raw_pkt->magic_num)){
- return -1;
- }
-
- reserved_hdr_len = calc_reserved_hdr_len(stream, &low_net_layer_type);
- if((reserved_hdr_len < 0) || (-1 == low_net_layer_type)){
- ret = -1;
- goto fun_exit;
- }
- tcp_rst_finger = make_tcp_rst_finger_mark(thread_num, (const raw_pkt_t *)raw_pkt);
- set_build_layer_ipv4_args(thread_num, tcp_rst_finger->ip_ttl, tcp_rst_finger->ip_id_host_order);
- set_build_layer_tcp_args(thread_num, TH_SYN|TH_ACK, tcp_rst_finger->tcp_win_host_order, MESA_rand());
-
- for(i = 0; i < KILL_TCP_SYN_ACK_NUM; i++){
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
-
- send_len = build_net_layer_pkt(stream_pr, ADDR_TYPE_TCP, 0, send_handle->send_buf + reserved_hdr_len, 1, raw_pkt);
- if(send_len < 0){
- ret = -1;
- goto fun_exit;
- }
- ret = packet_io_send(send_handle, reserved_hdr_len, SEND_TYPE_LINK_INJECT,
- low_net_layer_type, stream->routedir ^ 1, thread_num,
- feedback_buf, feedback_buf_len);
- if(ret < 0){
- send_handle->tot_send_err++;
- }else{
- send_handle->tot_send_pkt++;
- send_handle->tot_send_byte += send_len;
- }
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
- g_SysInputInfo[thread_num][SEND_TCP_SYN_ACK]++;
- g_SysInputInfo[thread_num][SEND_TCP_SYN_ACK_LEN]+=send_len;
- }
-fun_exit:
- detach_build_layer_ipv4_args(thread_num);
- detach_build_layer_tcp_args(thread_num);
-
- stream_pr->stream_killed_flag = 1;
-
- return ret;
-}
-
-int MESA_kill_tcp_synack(struct streaminfo *stream, const void *ext_raw_pkt)
-{
- return __do_kill_tcp_synack(stream, ext_raw_pkt, (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-}
-
-int MESA_kill_tcp_synack_feedback(struct streaminfo *stream, const void *ext_raw_pkt,
- char *feedback_buf, int *feedback_buf_len)
-{
- if((NULL == feedback_buf) || (NULL == feedback_buf_len)){
- return -2;
- }
- if(*feedback_buf_len <= 0){
- return -2;
- }
-
- return __do_kill_tcp_synack(stream, ext_raw_pkt, feedback_buf, feedback_buf_len);
-}
-
-
-/* 2014-11-15 lijia add, for drop NO-TCP protocol in serial mode.
- return value:
- >= 0: success.
- -1 : error.
-*/
-int MESA_kill_connection(struct streaminfo *stream, const void *ext_raw_pkt)
-{
- int ret;
- struct streaminfo_private *stream_pr;
-
- (void)ext_raw_pkt;
-
- if(NULL == stream){
- return -1;
- }
- stream_pr = (struct streaminfo_private *)stream;
-
- switch(stream->type){
- case STREAM_TYPE_TCP:
- //ret = MESA_kill_tcp(stream, ext_raw_pkt);
- /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ, ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */
- ret = MESA_kill_tcp(stream, stream_pr->raw_pkt);
- break;
- case STREAM_TYPE_UDP:
- stream_pr->stream_killed_flag = 1;
- ret = 0;
- break;
-
- case STREAM_TYPE_SOCKS4:
- case STREAM_TYPE_SOCKS5:
- case STREAM_TYPE_HTTP_PROXY:
- case STREAM_TYPE_PPPOE:
- //TODO
- printf("stream type: %d, not support kill_connection!\n", stream->type);
- return -1;
- //assert(0);
- break;
-
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-int MESA_kill_connection_feedback(struct streaminfo *stream, const void *ext_raw_pkt,
- char *feedback_buf, int *feedback_buf_len)
-{
- int ret;
- struct streaminfo_private *stream_pr;
-
- (void)ext_raw_pkt;
-
- if((NULL == feedback_buf) || (NULL == feedback_buf_len)){
- return -2;
- }
- if(*feedback_buf_len <= 0){
- return -2;
- }
-
- if(NULL == stream){
- return -1;
- }
- stream_pr = (struct streaminfo_private *)stream;
-
- switch(stream->type){
- case STREAM_TYPE_TCP:
- //ret = MESA_kill_tcp(stream, ext_raw_pkt);
- /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ, ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */
- ret = MESA_kill_tcp_feedback(stream, stream_pr->raw_pkt, feedback_buf, feedback_buf_len);
- break;
- case STREAM_TYPE_UDP:
- stream_pr->stream_killed_flag = 1;
- ret = 0;
- break;
-
- case STREAM_TYPE_SOCKS4:
- case STREAM_TYPE_SOCKS5:
- case STREAM_TYPE_HTTP_PROXY:
- case STREAM_TYPE_PPPOE:
- //TODO
- printf("stream type: %d, not support kill_connection!\n", stream->type);
- return -1;
- //assert(0);
- break;
-
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-static int __do_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len,
- const void *ext_raw_pkt, UCHAR snd_routedir,
- char *feedback_buf, int *feedback_buf_len)
-{
- int ret = -1, reserved_hdr_len, send_len = 0;
- MESA_send_handle *send_handle;
- int thread_num = stream->threadnum;
- int low_net_layer_type;
- int snd_dir_reverse;
- const raw_pkt_t *raw_pkt;
- struct streaminfo_private *stream_pr;
-
- (void)ext_raw_pkt;
-
- if(NULL == stream){
- return -1;
- }
-
- if(dir_check(snd_routedir) < 0){
- return -1;
- }
-
- stream_pr = (struct streaminfo_private *)stream;
- /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ, ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */
- raw_pkt = (const raw_pkt_t *)stream_pr->raw_pkt;
- if((NULL == raw_pkt) || (RAW_PKT_MAGIC_NUM != raw_pkt->magic_num)){
- return -1;
- }
-
- snd_dir_reverse = ((snd_routedir == stream->routedir) ? 0: 1);
-
- send_handle = &g_send_handle[thread_num];
-
- reserved_hdr_len = calc_reserved_hdr_len(stream, &low_net_layer_type);
- if((reserved_hdr_len < 0) || (-1 == low_net_layer_type)){
- ret = -1;
- goto fun_exit;
- }
-
- if(payload_len + reserved_hdr_len > MTU_MAX){
- sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: MESA_inject_pkt() error! payload_len too long:%d.\n", __FILE__, __LINE__, payload_len + reserved_hdr_len);
- return -1;
- //assert(0);
- }
-
- if((ADDR_TYPE_IPV4 == stream->addr.addrtype)
- || (ADDR_TYPE_TCP == stream->addr.addrtype)){
- set_build_layer_tcp_args(thread_num, TH_PUSH|TH_ACK, MESA_rand_range(1000, 1460), 0);
- }
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
-
- memcpy(send_handle->send_buf + reserved_hdr_len, payload, payload_len);
-
- send_len = build_net_layer_pkt(stream_pr, stream->addr.addrtype, payload_len,
- send_handle->send_buf + reserved_hdr_len, snd_dir_reverse, raw_pkt);
- if(send_len < 0){
- ret = -1;
- goto err;
- }
- ret = packet_io_send(send_handle, reserved_hdr_len+payload_len, SEND_TYPE_LINK_INJECT,
- low_net_layer_type, stream->routedir, thread_num,
- feedback_buf, feedback_buf_len);
- if(ret < 0){
- send_handle->tot_send_err++;
- }else{
- send_handle->tot_send_pkt++;
- send_handle->tot_send_byte += send_len;
- }
-
- if(STREAM_TYPE_TCP == stream->type){
- g_SysInputInfo[thread_num][SEND_TCP_PKT]++;
- g_SysInputInfo[thread_num][SEND_TCP_PKT_LEN]+=send_len;
- }else{
- g_SysInputInfo[thread_num][SEND_UDP_PKT]++;
- g_SysInputInfo[thread_num][SEND_UDP_PKT_LEN]+=send_len;
- }
-
-err:
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num);
-
-fun_exit:
- if((ADDR_TYPE_IPV4 == stream->addr.addrtype)
- || (ADDR_TYPE_TCP == stream->addr.addrtype)){
- detach_build_layer_tcp_args(thread_num);
- }
-
- return ret;
-}
-
-int MESA_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len,
- const void *ext_raw_pkt, UCHAR snd_routedir)
-{
- return __do_inject_pkt(stream, payload, payload_len, ext_raw_pkt, snd_routedir,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-}
-
-
-int MESA_inject_pkt_feedback(struct streaminfo *stream, const char *payload, int payload_len,
- const void *ext_raw_pkt, UCHAR snd_routedir,
- char *feedback_buf, int *feedback_buf_len)
-{
- if((NULL == feedback_buf) || (NULL == feedback_buf_len)){
- return -2;
- }
- if(*feedback_buf_len <= 0){
- return -2;
- }
-
- return __do_inject_pkt(stream, payload, payload_len, ext_raw_pkt, snd_routedir,
- feedback_buf, feedback_buf_len);
-}
-
-unsigned long packet_io_get_send_pkt_num(int thread_num)
-{
- MESA_send_handle *send_handle = &g_send_handle[thread_num];
-
- return send_handle->tot_send_pkt;
-}
-
-unsigned long packet_io_get_send_pkt_err(int thread_num)
-{
- MESA_send_handle *send_handle = &g_send_handle[thread_num];
-
- return send_handle->tot_send_err;
-}
-
-unsigned long packet_io_get_send_pkt_byte(int thread_num)
-{
- MESA_send_handle *send_handle = &g_send_handle[thread_num];
-
- return send_handle->tot_send_byte;
-}
-
-int packet_io_set_max_rand_value(int rand_max)
-{
- g_iMaxRandVal = rand_max;
- return 0;
-}
-
-int packet_io_set_rand_key(int rand_key)
-{
- g_iRandKey = rand_key;
- return 0;
-}
-
-static int send_handle_init(int tot_thread_num)
-{
- int i, ret;
- int max_thread_num;
-#if 0 /* 2018 lijia modify , ���Ӳ���������߳������������� */
- for(i = 0; i < tot_thread_num; i++){
-#else
- max_thread_num = ((tot_thread_num) >= (INDEPENDENT_SEND_QUEUE_MAX_NUM)) ? (tot_thread_num) : (INDEPENDENT_SEND_QUEUE_MAX_NUM);
- for(i = 0; i < max_thread_num; i++){
-#endif
- g_send_handle[i].raw_ipv4_fd = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
- if(g_send_handle[i].raw_ipv4_fd < 0){
- printf("socket v4 error, %s\n", strerror(errno));
- return -1;
- }
- if(g_packet_io_ipv6_raw_socket){
- g_send_handle[i].raw_ipv6_fd = socket(PF_INET6, SOCK_RAW, IPPROTO_RAW);
- if(g_send_handle[i].raw_ipv6_fd < 0){
- printf("socket v6 error, %s\n", strerror(errno));
- printf("Please disable IPv6 module, then try again!\n");
- return -1;
- }
- }
- if(g_send_dev_name[0] != '\0'){
- ret = g_send_handle[i].raw_eth_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
- if(g_send_handle[i].raw_eth_fd < 0){
- printf("socket raw eth error, %s\n", strerror(errno));
- return -1;
- }
- ret = snprintf(g_send_handle[i].saddr_raw_eth.sa_data, sizeof(g_send_handle[i].saddr_raw_eth.sa_data),
- "%s", g_send_dev_name);
- if(ret >= (int)sizeof(g_send_handle[i].saddr_raw_eth.sa_data)){
- printf("send device name is too long!\n");
- return -1;
- }
- g_send_handle[i].saddr_raw_eth.sa_family = PF_INET;
- }
- g_send_handle[i].threadnum = i;
-
-#if (0 == SAPP_AS_TARGET_SO)
- g_send_handle[i].low_level_send_handle = dl_io_fun_list.dl_io_get_send_handle(i);
- if(NULL == g_send_handle[i].low_level_send_handle){
- printf("dl_io_get_send_handle error !\n");
- return -1;
- }
-#endif
- g_packet_dl_send_handle[i] = g_send_handle[i].low_level_send_handle; /* 20161117 lijia move from packet_io_init() */
- }
-
- return 0;
-}
-
-/* 2015-01-04 lijia add, ��pappƽ̨Ǩ�Ƶ�sappƽ̨, �ײ㷢���ӿڲ�ͬ */
-int MESA_sendpacket_ethlayer(int thread_num,const char *data, int data_len, unsigned int target_id)
-{
- int ret;
-
- if(data_len > MTU_MAX)
- {
- printf("data length is more than MTU, %d\n", data_len);
- return -1;
- }
-
-#if 0 /* for debug! */
- char send_buf[MTU_MAX];
- char debug_smac[6] = {0x74, 0x86, 0x7A, 0xD0, 0x12, 0xFC};
- char debug_dmac[6] = {0x00, 0x01, 0x6c, 0x53, 0xa9, 0x94};
- struct mesa_ethernet_hdr *eth_hdr = (struct mesa_ethernet_hdr *)data;
- eth_hdr->ether_type = ntohs(ETHERTYPE_IP);
- memcpy(eth_hdr->ether_shost, debug_smac, 6);
- memcpy(eth_hdr->ether_dhost, debug_dmac, 6);
-#endif
-
- ret = packet_io_send_raw(thread_num, (char *)data, data_len, target_id);
-
- return (ret);
-}
-
-int sendpacket_init_new(int tot_thread_num)
-{
- srand(time(NULL));
-
- g_rand_seed = random();
-
- if(send_handle_init(tot_thread_num) < 0){
- return -1;
- }
-
- /* to do, TODO,
- //get_gateway_info();
-
- ����һ���߳�, ��̬��ȡĬ�����ص�MAC��ַ, ����Ŀ�������IPv4��ַ����������IP,����arp����,
- pthread_create(sendpacket_keepalive_with_gateway);
- */
-
- return 0;
-}
-
-
-#define DIR_BIT_USE_MASK (0x81)
-#define DIR_BIT_UNUSE_MASK (0x7E)
-
-
-/***************************************************************************************
- NOTE:
- MESA_sendpacket_xxx��MESA_fakepacket_send_xxxϵ�к�����, dir��sapp�е�routedir���岻ͬ,
- pappƽ̨�е�dirʹ�����λbit��ʾ����, ������Ϊ0x00, ����Ϊ0x80,
- ��sapp�е�routedir�����λ��ʾ����, ������Ϊ0x00, ����Ϊ0x01.
- Ϊ��ͬʱ���ݴ�����ƽ̨�Ͳ��, ����MESA_dir_reverse()����, ���ڷ���.
-****************************************************************************************/
-unsigned char MESA_dir_reverse(unsigned char raw_dir)
-{
- raw_dir ^= DIR_BIT_USE_MASK; /* ͬʱ����sapp�;ɰ�WY���, ��ߺ����bitλͬʱ���� */
-
- return raw_dir;
-}
-
-static inline int dir_check(unsigned char raw_dir)
-{
- if(raw_dir & DIR_BIT_UNUSE_MASK){ /* ����ֻʹ������ߺ����λbit, �����������ֵ,˵�������ת��dirʱ���˴��� */
- printf("dir = 0x%x, is invalid, only the most or least significant bit can be used!", raw_dir);
- //assert(0);
- return -1;
- }
-
- return 0;
-}
-
-static int __MESA_sendpacket_iplayer(int thread_index,const char *data, int data_len, u_int8_t dir, int layer_type)
-{
- MESA_send_handle *send_handle;
- int ret, offset = 0;
-
- send_handle = &g_send_handle[thread_index];
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
- case CAP_LEVEL_MAC:
- offset = sizeof(struct mesa_ethernet_hdr);
- break;
-
- default:
- printf("MESA_sendpacket_iplayer: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- //exit(1);
- return -1;
- }
-
- if(data_len > (int)MTU_MAX-(int)sizeof(struct mesa_ethernet_hdr)){
- printf("TODO: MESA_sendpacket_iplayer error! datalen is more than MTU, need ip fragment!\n");
- return -1;
- }
-
- memcpy(send_handle->send_buf + offset, data, data_len);
-
- ret = packet_io_send_fake_pkt(send_handle, data_len+sizeof(struct mesa_ethernet_hdr), SEND_TYPE_LINK_INJECT,
- layer_type, dir, thread_index,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- g_SysInputInfo[thread_index][SEND_IP_RAW_PKT]++;
- g_SysInputInfo[thread_index][SEND_IP_RAW_PKT_LEN]+=ret;
-
- return ret;
-}
-
-int MESA_sendpacket_iplayer(int thread_index,const char *data, int data_len, u_int8_t dir)
-{
- return __MESA_sendpacket_iplayer(thread_index, data, data_len, dir, __ADDR_TYPE_IP_PAIR_V4);
-}
-
-int MESA_sendpacket_ipv6_layer(int thread_index,const char *data, int data_len, u_int8_t dir)
-{
- return __MESA_sendpacket_iplayer(thread_index, data, data_len, dir, __ADDR_TYPE_IP_PAIR_V6);
-}
-
-int MESA_fakepacket_send_ipv4(int thread_index,u_int8_t ttl,
- u_int8_t protocol,u_int32_t sip, u_int32_t dip, const char *payload,
- int payload_len,u_int8_t dir)
-{
- MESA_send_handle *send_handle;
- int ret, offset = 0;
- u_int16_t ipid;
-
- send_handle = &g_send_handle[thread_index];
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
- case CAP_LEVEL_MAC:
- offset = sizeof(struct mesa_ethernet_hdr);
- break;
-
- default:
- printf("MESA_fakepacket_send_ipv4: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- //exit(1);
- return -1;
- }
-
- if(payload_len > (int)MTU_MAX-(int)sizeof(struct mesa_ethernet_hdr)-(int)sizeof(struct mesa_ip4_hdr)){
- printf("TODO: MESA_fakepacket_send_ipv4 error! datalen is more than MTU, need ip fragment!\n");
- return -1;
- }
-
- ipid = MESA_rand() % 65535;
- sendpacket_build_ipv4(payload_len, 0, ipid, 0 , ttl, protocol,
- htonl(sip), htonl(dip), payload, payload_len, send_handle->send_buf+offset);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr),
- SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- g_SysInputInfo[thread_index][SEND_IP_PKT]++;
- g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=ret;
-
- return ret;
-}
-
-int MESA_fakepacket_send_ipv4_detail(int thread_index,u_int8_t ttl,
- u_int8_t protocol,u_int32_t sip, u_int32_t dip, u_int16_t ipid,
- const char *payload, int payload_len,u_int8_t dir)
-{
- MESA_send_handle *send_handle;
- int ret, offset = 0;
-
- send_handle = &g_send_handle[thread_index];
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
- case CAP_LEVEL_MAC:
- offset = sizeof(struct mesa_ethernet_hdr);
- break;
-
- default:
- printf("MESA_fakepacket_send_ipv4: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- //exit(1);
- return -1;
- }
-
- if(payload_len > (int)MTU_MAX-(int)sizeof(struct mesa_ethernet_hdr)-(int)sizeof(struct mesa_ip4_hdr)){
- printf("TODO: MESA_fakepacket_send_ipv4 error! datalen is more than MTU, need ip fragment!\n");
- return -1;
- }
-
- sendpacket_build_ipv4(payload_len, 0, ipid, 0 , ttl, protocol,
- htonl(sip), htonl(dip), payload, payload_len, send_handle->send_buf+offset);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr),
- SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- g_SysInputInfo[thread_index][SEND_IP_PKT]++;
- g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=ret;
-
- return ret;
-}
-
-int MESA_fakepacket_send_tcp(int thread_index,u_int sip_host_order,u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control,const char* payload,int payload_len, u_int8_t dir)
-{
- MESA_send_handle *send_handle;
- int ret, offset = 0;
- u_int16_t tcp_win, ipid;
-
- send_handle = &g_send_handle[thread_index];
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
- case CAP_LEVEL_MAC:
- offset = sizeof(struct mesa_ethernet_hdr);
- break;
-
- default:
- printf("MESA_fakepacket_send_tcp: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- //exit(1);
- return -1;
- }
-
- if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){
- printf("TODO: MESA_fakepacket_send_tcp error! datalen is more than MTU, need ip fragment!\n");
- return -1;
- }
-
- tcp_win = MESA_rand_range(1460, 65500);
- ipid = MESA_rand() % 65535;
-
- sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order,
- control, tcp_win, 0, payload, payload_len, send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr));
-
- sendpacket_build_ipv4(payload_len+SENDPACKET_TCP_H, 0, ipid, 0, 64, IPPROTO_TCP,
- htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_tcp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr),
- SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- g_SysInputInfo[thread_index][SEND_TCP_PKT]++;
- g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=ret;
-
- return ret;
-}
-
-
-int MESA_fakepacket_send_tcp_detail(int thread_index,u_int sip_host_order,u_int dip_host_order,
- u_short ipid, u_char ip_ttl,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control, u_short tcp_win, const char* payload,int payload_len, u_int8_t dir)
-{
- MESA_send_handle *send_handle;
- int ret, offset = 0;
-
- send_handle = &g_send_handle[thread_index];
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
- case CAP_LEVEL_MAC:
- offset = sizeof(struct mesa_ethernet_hdr);
- break;
-
- default:
- printf("MESA_fakepacket_send_tcp: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- //exit(1);
- return -1;
- }
-
- if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){
- printf("TODO: MESA_fakepacket_send_tcp error! datalen is more than MTU, need ip fragment!\n");
- return -1;
- }
-
- sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order,
- control, tcp_win, 0, payload, payload_len, send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr));
-
- sendpacket_build_ipv4(payload_len+SENDPACKET_TCP_H, 0, ipid, 0, ip_ttl, IPPROTO_TCP,
- htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_tcp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr),
- SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- g_SysInputInfo[thread_index][SEND_TCP_PKT]++;
- g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=ret;
-
- return ret;
-}
-
-int MESA_fakepacket_send_udp(int thread_index, u_int sip_host_order, u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir)
-{
- MESA_send_handle *send_handle;
- int ret, offset = 0;
- u_int16_t ipid;
-
- send_handle = &g_send_handle[thread_index];
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
- case CAP_LEVEL_MAC:
- offset = sizeof(struct mesa_ethernet_hdr);
- break;
-
- default:
- printf("MESA_fakepacket_send_udp: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- //exit(1);
- return -1;
- }
-
- if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){
- printf("TODO: MESA_fakepacket_send_udp error! datalen is more than MTU, need ip fragment!\n");
- return -1;
- }
-
- ipid = MESA_rand() % 65535;
-
- sendpacket_build_udp_dual_stack(sport_host_order, dport_host_order, payload, payload_len, payload_len,
- send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr));
-
- sendpacket_build_ipv4(payload_len+SENDPACKET_UDP_H, 0, ipid, 0, 64, IPPROTO_UDP,
- htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_udp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr),
- SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- g_SysInputInfo[thread_index][SEND_UDP_PKT]++;
- g_SysInputInfo[thread_index][SEND_UDP_PKT_LEN]+=ret;
-
- return ret;
-}
-
-int MESA_fakepacket_send_udp_detail(int thread_index, u_int sip_host_order, u_int dip_host_order,
- u_short ipid, u_int8_t ip_ttl, u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir)
-{
- MESA_send_handle *send_handle;
- int ret, offset = 0;
-
- send_handle = &g_send_handle[thread_index];
-
- send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
- switch(g_packet_io_cap_level){
- case CAP_LEVEL_IPV4:
- offset = 0;
- break;
- case CAP_LEVEL_MAC:
- offset = sizeof(struct mesa_ethernet_hdr);
- break;
-
- default:
- printf("MESA_fakepacket_send_udp: Invalid cap_mode:%d\n", g_packet_io_cap_level);
- //exit(1);
- return -1;
- }
-
- if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){
- printf("TODO: MESA_fakepacket_send_udp error! datalen is more than MTU, need ip fragment!\n");
- return -1;
- }
-
- sendpacket_build_udp_dual_stack(sport_host_order, dport_host_order, payload, payload_len, payload_len,
- send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr));
-
- sendpacket_build_ipv4(payload_len+SENDPACKET_UDP_H, 0, ipid, 0, ip_ttl, IPPROTO_UDP,
- htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len);
-
- sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_udp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr),
- SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index,
- (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER);
-
- packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index);
-
- g_SysInputInfo[thread_index][SEND_UDP_PKT]++;
- g_SysInputInfo[thread_index][SEND_UDP_PKT_LEN]+=ret;
-
- return ret;
-}
-
-#if IOMODE_MARSIO
-#include "marsio.h"
-#include "mrtunnat.h"
-#include <dlfcn.h>
-static struct mr_instance *dl_io_marsio4_instance = NULL;
-extern struct dl_io_lib_name g_dl_io_lib_info[];
-extern int g_packet_io_cap_mode;
-extern int marsio_send_burst_with_options_for_tcpdumpmesa(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[], int nr_mbufs, uint16_t options);
-static mr_instance *sapp_get_marsio_instance(void)
-{
- void *dl_handle;
- char lib_path[256];
- void *address_of_sapp_marsio4_instance;
-
- snprintf(lib_path, 256, "%s/%s", "platform_lib", g_dl_io_lib_info[g_packet_io_cap_mode].lib_name);
-
- dl_handle = dlopen(lib_path, RTLD_NOW);
- if(NULL == dl_handle){
- printf("\033[41m[Error]dlopen %s error!\033[0m\n", lib_path);
- return NULL;
- }
-
- address_of_sapp_marsio4_instance = dlsym(dl_handle, "sapp_marsio4_instance");
- if(NULL == address_of_sapp_marsio4_instance){
- printf("\033[41m[Error]dlsym %s from %s error!\033[0m\n", "sapp_marsio4_instance", lib_path);
- return NULL;
- }
-
- /* dlsym ��ȡ����sapp_marsio4_instance���ŵ���ʼ��ַ, �Դ˵�ַȡ8bytesֵ, ����ָ�����ʵֵ */
- memcpy(&dl_io_marsio4_instance, address_of_sapp_marsio4_instance, sizeof(void *));
- return dl_io_marsio4_instance;
-}
-
-
-static void sapp_fakepacket_set_vxlan_options(struct mr_tunnat_ctrlzone *mr_ctrlzone, SAPP_TLV_T *option)
-{
- switch(option->type){
- case SAPP_SEND_OPT_GDEV_DMAC:
- memcpy(mr_ctrlzone->g_device_mac, option->array_value, 6);
- break;
-
- case SAPP_SEND_OPT_GDEV_SMAC:
- memcpy(mr_ctrlzone->l_device_mac, option->array_value, 6);
- break;
-
- case SAPP_SEND_OPT_GDEV_DIP:
- mr_ctrlzone->g_device_in_addr = option->int_value;
- break;
-
- case SAPP_SEND_OPT_GDEV_SIP:
- mr_ctrlzone->l_device_in_addr = option->int_value;
- break;
-
- case SAPP_SEND_OPT_GDEV_UDP_DPORT:
- /* default 4789, do nothing */
- break;
-
- case SAPP_SEND_OPT_GDEV_UDP_SPORT:
- mr_ctrlzone->l4_src_port = option->short_value;
- break;
-
- case SAPP_SEND_OPT_VXLAN_VPN_ID:
- mr_ctrlzone->g_device_vpn_id = option->int_value;
- mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_NO_SESSION; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */
- break;
-
- case SAPP_SEND_OPT_VXLAN_LINK_ID:
- mr_ctrlzone->g_device_linkpair = option->int_value;
- mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_NO_SESSION; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */
- break;
-
- case SAPP_SEND_OPT_VXLAN_LINK_ENCAP_TYPE:
- mr_ctrlzone->g_device_outer_encap_type = option->char_value;
- break;
-
- case SAPP_SEND_OPT_VXLAN_LINK_DIR:
- mr_ctrlzone->route_dir = option->char_value;
- mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_NO_SESSION; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */
- break;
-
- case SAPP_SEND_OPT_INNER_LINK_ENCAP_TYPE:
- mr_ctrlzone->g_device_inner_encap_type = option->char_value;
- break;
-
- case SAPP_SEND_OPT_VXLAN_FLAGS:
- //todo, dpdk driver not support, fix value 0x08
- break;
-
- default:
- sapp_runtime_log(20, "sendpacket set vxlan options error, invalid opt type:%d\n", option->type);
- break;
- }
-
- return;
-}
-
-/*
- �˺�����ipv4, ipv6������������, ��ether_type_host��������.
- data: ����ipͷ��������ip��;
- data_len: ����ipͷ������.
-*/
-static int __MESA_sendpacket_iplayer_options(int thread_index,const char *data, int data_len,
- u_int8_t dir, SAPP_TLV_T *options, int opt_num, unsigned short ether_type_host)
-{
- /* marsioϵ�к���0��ʾ����, -1��ʾ����, g_serialϵ�к������������ֽ���, ����-1 */
- int inner_ret;
- marsio_buff_t *send_mbuf[1];
- unsigned char *real_buf;
- struct mr_tunnat_ctrlzone mr_ctrlzone;
- int i;
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index);
- if(inner_ret < 0){
- return -1;
- }
- g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++;
-
- real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], data_len+sizeof(struct mesa_ethernet_hdr));
- struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf;
- inner_ehdr->ether_type = ntohs(ether_type_host);/* �ײ���Ϊethernet */
-
- /* �˴�ֻ������IP����ص�ѡ��, vxlan���ѡ���ڹ�������sapp_fakepacket_set_vxlan_options()���� */
- memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone));
- for(i = 0; i < opt_num; i++){
- if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){
- memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN);
- }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){
- memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN);
- }else{
- sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]);
- }
- }
- memcpy(real_buf + sizeof(struct mesa_ethernet_hdr), data, data_len);
-
- mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */
- marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
- inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index,
- send_mbuf, 1, MARSIO_SEND_OPT_FAST);
- if(inner_ret < 0){
- return -1;
- }
-
- g_SysInputInfo[thread_index][SEND_IP_PKT]++;
- g_SysInputInfo[thread_index][SEND_IP_PKT_LEN] += data_len;
-
- g_SysInputInfo[thread_index][PKT_MARSIO_SND]++;
-
- return data_len;
-}
-
-
-int MESA_sendpacket_iplayer_options(int thread_index,const char *data, int data_len,
- u_int8_t dir, SAPP_TLV_T *options, int opt_num)
-{
- return __MESA_sendpacket_iplayer_options(thread_index, data, data_len, dir, options, opt_num, ETHERTYPE_IP);
-}
-
-int MESA_sendpacket_ipv6_layer_options(int thread_index,const char *data, int data_len,
- u_int8_t dir, SAPP_TLV_T *options, int opt_num)
-{
- return __MESA_sendpacket_iplayer_options(thread_index, data, data_len, dir, options, opt_num, ETHERTYPE_IPv6);
-}
-
-int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol,
- uint32_t sip_host_order, uint32_t dip_host_order,
- const char *payload, int payload_len, uint8_t dir,
- SAPP_TLV_T *options, int opt_num)
-{
- int snd_len, inner_ret;
- marsio_buff_t *send_mbuf[1];
- u_int16_t ipid = MESA_rand() & 0xFFFF;
- u_int8_t ip_ttl = MESA_rand() % 64 + 32;
- int thread_index = stream->threadnum;
- int i;
-
- struct mr_tunnat_ctrlzone mr_ctrlzone;
- unsigned char *real_buf;
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index);
- if(inner_ret < 0){
- return -1;
- }
- g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++;
-
- /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
- real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr));
- struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf;
- inner_ehdr->ether_type = ntohs(ETHERTYPE_IP);/* �ײ���Ϊethernte */
-
- /* �˴�ֻ������IP����ص�ѡ��, vxlan���ѡ���ڹ�������sapp_fakepacket_set_vxlan_options()���� */
- memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone));
- for(i = 0; i < opt_num; i++){
- if(SAPP_SEND_OPT_IP_ID == options[i].type){
- ipid = options[i].short_value;
- }else if(SAPP_SEND_OPT_IP_TTL == options[i].type){
- ip_ttl = options[i].char_value;
- }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){
- memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN);
- }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){
- memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN);
- }else{
- sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]);
- }
- }
- sendpacket_build_ipv4(payload_len, 0, ipid, 0 , ip_ttl, protocol,
- htonl(sip_host_order), htonl(dip_host_order), payload, payload_len,
- (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr));
-
- sendpacket_do_checksum(real_buf + sizeof(struct mesa_ethernet_hdr), IPPROTO_IP, SENDPACKET_IP_H);
-
- if(payload){
- memcpy(real_buf + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), payload, payload_len);
- }
-
- mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */
- marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
- inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index,
- send_mbuf, 1, MARSIO_SEND_OPT_FAST);
-
- if(inner_ret < 0){
- return -1;
- }
-
- snd_len = sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr) + payload_len;
- g_SysInputInfo[thread_index][SEND_IP_PKT]++;
- g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=snd_len;
-
- g_SysInputInfo[thread_index][PKT_MARSIO_SND]++;
-
- return snd_len;
-}
-
-int MESA_fakepacket_send_ipv6_options(const struct streaminfo *stream, uint8_t protocol,
- struct in6_addr *sip, struct in6_addr *dip,
- const char *payload, int payload_len, uint8_t dir,
- SAPP_TLV_T *options, int opt_num)
-{
- int inner_ret, snd_len;
- u_int8_t ip_ttl = MESA_rand() % 64 + 32;
- int thread_index = stream->threadnum;
- int i;
- marsio_buff_t *send_mbuf[1];
- struct mr_tunnat_ctrlzone mr_ctrlzone;
- unsigned char *real_buf;
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index);
- if(inner_ret < 0){
- return -1;
- }
- g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++;
-
- /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
- real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr));
- struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf;
- inner_ehdr->ether_type = ntohs(ETHERTYPE_IPv6);/* �ײ���Ϊethernet */
-
- /* �˴�ֻ������IP����ص�ѡ��, vxlan���ѡ���ڹ�������sapp_fakepacket_set_vxlan_options()���� */
- memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone));
- for(i = 0; i < opt_num; i++){
- if(SAPP_SEND_OPT_IP_TTL == options[i].type){
- ip_ttl = options[i].char_value;
- }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){
- memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN);
- }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){
- memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN);
- }else{
- sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]);
- }
- }
- sendpacket_build_ipv6(0, 0, payload_len, protocol, ip_ttl, sip, dip,
- payload, payload_len,
- (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr));
-
- mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */
- marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
- inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index,
- send_mbuf, 1, MARSIO_SEND_OPT_FAST);
- if(inner_ret < 0){
- return -1;
- }
-
- snd_len = sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr) + payload_len;
- g_SysInputInfo[thread_index][SEND_IP_PKT]++;
- g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=snd_len;
-
- g_SysInputInfo[thread_index][PKT_MARSIO_SND]++;
-
- return snd_len;
-}
-
-int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream,
- u_int sip_host_order,u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control,
- const char* payload,int payload_len, u_int8_t dir,
- SAPP_TLV_T *options, int opt_num)
-{
- int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr);
- int thread_index = stream->threadnum;
- marsio_buff_t *send_mbuf[1];
- struct mr_tunnat_ctrlzone mr_ctrlzone;
- unsigned char *real_buf;
- unsigned short ipid = MESA_rand() & 0xFFFF;
- unsigned short tcp_win = MESA_rand_range(8192, 32768);
- unsigned char ip_ttl = MESA_rand_range(32,65);
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index);
- if(inner_ret < 0){
- return -1;
- }
- g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++;
-
- /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
- real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr));
- struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf;
- inner_ehdr->ether_type = ntohs(ETHERTYPE_IP);/* �ײ���Ϊethernte */
-
- memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone));
- for(i = 0; i < opt_num; i++){
- if(SAPP_SEND_OPT_IP_ID == options[i].type){
- ipid = options[i].short_value;
- }else if(SAPP_SEND_OPT_IP_TTL == options[i].type){
- ip_ttl = options[i].char_value;
- }if(SAPP_SEND_OPT_TCP_WIN == options[i].type){
- tcp_win = options[i].short_value;
- }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){
- memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN);
- }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){
- memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN);
- }else{
- sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]);
- }
- }
-
- sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order,
- control, tcp_win, 0, payload, payload_len, real_buf+offset+sizeof(struct mesa_ip4_hdr));
-
- sendpacket_build_ipv4(payload_len+SENDPACKET_TCP_H, 0, ipid, 0, ip_ttl, IPPROTO_TCP,
- htonl(sip_host_order), htonl(dip_host_order), NULL, 0, real_buf+offset);
-
- sendpacket_do_checksum(real_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len);
-
- sendpacket_do_checksum(real_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */
- marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
- inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index,
- send_mbuf, 1, MARSIO_SEND_OPT_FAST);
-
- if(inner_ret < 0){
- return -1;
- }
-
- snd_len = sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_tcp_hdr) + payload_len;
-
- g_SysInputInfo[thread_index][SEND_TCP_PKT]++;
- g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len;
-
- g_SysInputInfo[thread_index][PKT_MARSIO_SND]++;
-
- return snd_len;
-}
-
-
-int MESA_fakepacket_send_ipv6_tcp_options(const struct streaminfo *stream,
- struct in6_addr *sip, struct in6_addr *dip,
- u_short sport_host_order,u_short dport_host_order,
- u_int sseq_host_order,u_int sack_host_order,
- u_char control,
- const char* payload,int payload_len, u_int8_t dir,
- SAPP_TLV_T *options, int opt_num)
-{
- int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr);
- int thread_index = stream->threadnum;
- marsio_buff_t *send_mbuf[1];
- struct mr_tunnat_ctrlzone mr_ctrlzone;
- unsigned char *real_buf;
- unsigned short tcp_win = MESA_rand_range(8192, 32768);
- unsigned char ip_ttl = MESA_rand_range(32,65);
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index);
- if(inner_ret < 0){
- return -1;
- }
- g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++;
-
- /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
- real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr));
- struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf;
- inner_ehdr->ether_type = ntohs(ETHERTYPE_IPv6);/* �ײ���Ϊethernte */
-
- memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone));
- for(i = 0; i < opt_num; i++){
- if(SAPP_SEND_OPT_IP_TTL == options[i].type){
- ip_ttl = options[i].char_value;
- }if(SAPP_SEND_OPT_TCP_WIN == options[i].type){
- tcp_win = options[i].short_value;
- }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){
- memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN);
- }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){
- memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN);
- }else{
- sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]);
- }
- }
-
- sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order,
- control, tcp_win, 0, payload, payload_len, real_buf+offset+sizeof(struct mesa_ip6_hdr));
-
- sendpacket_build_ipv6(0, 0, payload_len + sizeof(struct mesa_tcp_hdr), IPPROTO_TCP, ip_ttl, sip, dip,
- NULL, 0,
- (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr));
-
- sendpacket_do_checksum(real_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len);
-
- mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */
- marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
- inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index,
- send_mbuf, 1, MARSIO_SEND_OPT_FAST);
- if(inner_ret < 0){
- return -1;
- }
-
- snd_len = sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_tcp_hdr) + payload_len;
- g_SysInputInfo[thread_index][SEND_TCP_PKT]++;
- g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len;
-
- g_SysInputInfo[thread_index][PKT_MARSIO_SND]++;
-
- return snd_len;
-}
-
-int MESA_fakepacket_send_udp_options(const struct streaminfo *stream,
- u_int sip_host_order, u_int dip_host_order,
- u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir,
- SAPP_TLV_T *options, int opt_num)
-{
- int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr);
- int thread_index = stream->threadnum;
- marsio_buff_t *send_mbuf[1];
- struct mr_tunnat_ctrlzone mr_ctrlzone;
- unsigned char *real_buf;
- unsigned short ipid = MESA_rand();
- unsigned char ip_ttl = MESA_rand_range(32, 64);
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index);
- if(inner_ret < 0){
- return -1;
- }
- g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++;
-
- /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
- real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr));
- struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf;
- inner_ehdr->ether_type = ntohs(ETHERTYPE_IP);/* �ײ���Ϊethernte */
-
- memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone));
- for(i = 0; i < opt_num; i++){
- if(SAPP_SEND_OPT_IP_ID == options[i].type){
- ipid = options[i].short_value;
- }else if(SAPP_SEND_OPT_IP_TTL == options[i].type){
- ip_ttl = options[i].char_value;
- }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){
- memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN);
- }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){
- memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN);
- }else{
- sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]);
- }
- }
-
- sendpacket_build_udp(sport_host_order, dport_host_order, payload, payload_len,
- real_buf+offset+sizeof(struct mesa_ip4_hdr));
-
- sendpacket_build_ipv4(payload_len+SENDPACKET_UDP_H, 0, ipid, 0, ip_ttl, IPPROTO_UDP,
- htonl(sip_host_order), htonl(dip_host_order), NULL, 0, real_buf+offset);
-
- sendpacket_do_checksum(real_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len);
-
- sendpacket_do_checksum(real_buf+offset, IPPROTO_IP, SENDPACKET_IP_H);
-
- if((mr_ctrlzone.action & TUNNAT_CZ_ACTION_ENCAP_NO_SESSION) == 0){
- mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- }
- mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */
- marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
- inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index,
- send_mbuf, 1, MARSIO_SEND_OPT_FAST);
-
- if(inner_ret < 0){
- return -1;
- }
-
- snd_len = sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_udp_hdr) + payload_len;
- g_SysInputInfo[thread_index][SEND_TCP_PKT]++;
- g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len;
-
- g_SysInputInfo[thread_index][PKT_MARSIO_SND]++;
-
- return snd_len;
-}
-
-int MESA_fakepacket_send_ipv6_udp_options(const struct streaminfo *stream,
- struct in6_addr *sip, struct in6_addr *dip,
- u_short sport_host_order,u_short dport_host_order,
- const char *payload, int payload_len,u_int8_t dir,
- SAPP_TLV_T *options, int opt_num)
-{
- int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr);
- int thread_index = stream->threadnum;
- marsio_buff_t *send_mbuf[1];
- struct mr_tunnat_ctrlzone mr_ctrlzone;
- unsigned char *real_buf;
- unsigned char ip_ttl = MESA_rand_range(32, 64);
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index);
- if(inner_ret < 0){
- return -1;
- }
- g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++;
-
- /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */
- real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr));
- struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf;
- inner_ehdr->ether_type = ntohs(ETHERTYPE_IPv6);/* �ײ���Ϊethernte */
-
- memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone));
- for(i = 0; i < opt_num; i++){
- if(SAPP_SEND_OPT_IP_TTL == options[i].type){
- ip_ttl = options[i].char_value;
- }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){
- memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN);
- }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){
- memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN);
- }else{
- sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]);
- }
- }
-
- sendpacket_build_udp(sport_host_order, dport_host_order, payload, payload_len,
- real_buf+offset+sizeof(struct mesa_ip6_hdr));
-
- sendpacket_build_ipv6(0, 0, payload_len + sizeof(struct mesa_udp_hdr), IPPROTO_UDP, ip_ttl, sip, dip,
- NULL, 0,
- (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr));
-
- sendpacket_do_checksum(real_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len);
-
- mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER;
- mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */
- marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone));
- inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index,
- send_mbuf, 1, MARSIO_SEND_OPT_FAST);
- if(inner_ret < 0){
- return -1;
- }
-
- snd_len = sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_udp_hdr) + payload_len;
- g_SysInputInfo[thread_index][SEND_TCP_PKT]++;
- g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len;
-
- g_SysInputInfo[thread_index][PKT_MARSIO_SND]++;
-
- return snd_len;
-}
-#endif
-
-int sapp_forward_current_pkt(const struct streaminfo *stream, unsigned int target_id)
-{
- int ret;
-#if IOMODE_MARSIO
- marsio_buff_t *raw_mbuf, *new_clone_buf;
- const struct streaminfo_private *stream_pr = (const struct streaminfo_private *)stream;
-
- if(NULL == dl_io_marsio4_instance){
- dl_io_marsio4_instance = sapp_get_marsio_instance();
- }
-
- if(NULL == stream_pr->raw_pkt){ /* ����������ʱ��̭����, ����Ե��ô˽ӿ� */
- return 0;
- }
-
- /* TODO:
- �жϵ�ǰ���Ƿ��������, ���ӷ������ص�TCPALL��,
- �������io_lib_pkt_referenceָ��dpdk���ڴ�, ��û�и��Ʊ���,
- ����ʱ�ᵼ���ڴ����.
-
- NOTE:
- ��ʵ���������ޱ�Ҫ, ת����������ص�TCPALL��, ��deal_unorder���������������TCPALL�ӿ�!
- */
- if((stream->addr.pkttype & PKT_TYPE_TCPREORDER) != 0){
- return 0;
- }
- raw_mbuf = (marsio_buff_t *)stream_pr->raw_pkt->io_lib_pkt_reference;
-
- assert(raw_mbuf);
-
- /* NOTE,
- marsio��ͬʱ���հ����������Ӧ����������ʱ��������,
- ���Դ˴�����Ӧ����������֮ǰ, ��cloneһ��new_clone_buf, ���ͺ���Զ�free.
- ��עԭʼ���Ļ���ԭ����raw_mbuf.
- */
- new_clone_buf = marsio_buff_clone_with_options(dl_io_marsio4_instance, raw_mbuf,
- MARSIO_SOCKET_ID_ANY, stream->threadnum,
- MR_BUFF_CLONE_BUFF | MR_BUFF_CLONE_CTRLZONE);
-
- assert(new_clone_buf);
- g_SysInputInfo[stream->threadnum][PKT_MARSIO_MALLOC]++;
-
- ret = marsio_send_burst((struct mr_sendpath *)g_packet_device_alias[target_id].dl_io_param,
- stream->threadnum, &new_clone_buf, 1);
- g_SysInputInfo[stream->threadnum][PKT_MARSIO_SND]++;
-
-#else
- printf("sapp_forward_current_pkt() not support in non-marsio mode, TODO!\n");
- return -1;/* ����ģʽtodo */
-#endif
-
- return ret;
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
+#ifdef __cplusplus +extern "C" { +#endif + +#include "sysinfo.h" +#include "mesa_net.h" +#include "stream_internal.h" +#include "packet_io_internal.h" +#include "packet_io.h" +#include <MESA/MESA_handle_logger.h> +#include <netinet/if_ether.h> +#include <netinet/in.h> +#include <net/if_arp.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <ctype.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> + + +#define KILL_TCP_RST_NUM (3) +#define KILL_TCP_SYN_ACK_NUM (3) + +typedef struct{ + UINT32 gateway_ip; /* network order */ + UINT8 gateway_mac[ETHER_ADDR_LEN]; + char to_gateway_device_name[DEV_NAME_STR_LEN]; +}sys_route_t; + +//static sys_route_t g_sys_route_info; +MESA_send_handle g_send_handle[MAX_THREAD_NUM]; +static volatile UINT64 g_rand_seed = 0x013579ABCDEF; + +/* ������ƽ̨����randֵ���㷨, ����У��RST���Ƿ�Ϊ��ϵͳ���� */ +static int randgroup[MAX_THREAD_NUM]; +static int g_iRandKey=13; +static int g_iMaxRandVal=65535; + +typedef struct{ + unsigned char ip_ttl; + unsigned short ip_id_host_order; + char __cache_align_pad_[60]; /* ���߳�ȫ�ֱ���, ��֤64�ֽ�cache����߽� */ +}bulid_layer_ipv4_args_t; + +typedef struct{ + int to_do; +}bulid_layer_ipv6_args_t; + +typedef struct{ + unsigned char tcp_flags; + unsigned short tcp_win_host_order; + unsigned int tcp_seq; + char __cache_align_pad_[56]; /* ���߳�ȫ�ֱ���, ��֤64�ֽ�cache����߽� */ +}bulid_layer_tcp_args_t; + + +typedef struct{ + unsigned char ip_ttl; + unsigned short ip_id_host_order; + unsigned short tcp_win_host_order; + char __cache_align_pad_[58]; /* ���߳�ȫ�ֱ���, ��֤64�ֽ�cache����߽� */ +}tcp_rst_finger_mark_t; + +static bulid_layer_ipv4_args_t g_build_ipv4_args[MAX_THREAD_NUM]; +//static bulid_layer_ipv6_args_t g_build_ipv6_args[MAX_THREAD_NUM]; +static bulid_layer_tcp_args_t g_build_tcp_args[MAX_THREAD_NUM]; +static layer_args_t g_build_pkt_args[MAX_THREAD_NUM]; + +static tcp_rst_finger_mark_t g_tcp_rst_finger[MAX_THREAD_NUM]; + +extern void *g_packet_dl_send_handle[MAX_THREAD_NUM]; +extern dl_io_fun_list_t dl_io_fun_list; +extern char g_send_dev_name[DEV_NAME_STR_LEN]; +extern int g_packet_io_ipv6_switch; +extern int g_packet_io_ipv6_raw_socket; +extern int g_app_send_rst_type ; +extern int g_packet_io_cap_level; +extern int calc_l2tp_hdr_len(const struct l2tp_hdr_v2 *l2tp_hdr); +extern int packet_io_send_fake_pkt(MESA_send_handle *send_handle,int datalen,int send_type, + int low_layer_type, int dir,int thread_num, + char *feedback_buf, int *feedback_buf_len); +static inline int dir_check(unsigned char raw_dir); + + +/* + �����յ����ֽ��������ϸ����ij��Ȳ�����ݰ��ĵ�ַ����, �õ����������������. +*/ +#if 0 +void random_seed(int pkt_len, UINT64 *pkt_rand) +{ + static int last_pkt_len = 0x1234567; + int diff = (pkt_len >= last_pkt_len)?(pkt_len-last_pkt_len):(last_pkt_len-pkt_len); + + g_rand_seed += (UINT64)pkt_len + (UINT64)diff + *pkt_rand; + + last_pkt_len = pkt_len; +} +#endif + + +UINT64 MESA_rand(void) +{ + return g_rand_seed ^ (UINT64)random(); +} + +/* return value: [start, end] */ +UINT64 MESA_rand_range(UINT64 start, UINT64 end) +{ + UINT64 rand_num = MESA_rand(); + + if(start > end){ + return end + rand_num % (start - end + 1); + } + + return start + rand_num % (end - start + 1); +} + + +int set_rst_rand_key(int rnd_key) +{ + g_iRandKey = rnd_key; + return 0; +} + +int set_rst_max_rnd_val(int max_rnd_val) +{ + g_iMaxRandVal = max_rnd_val; + return 0; +} + +/* + Ϊ�˼����ϰ�ϵͳ, ���ٱ�ϵͳ������RST��. + IN ARG: + sip, dip: network order; + + OUT ARG: + ipid, win: host order; +*/ +static void trick_algo_getrandval(int thread_id,unsigned sip,unsigned dip,unsigned short *ipid,unsigned short *win,u_char *ttl) +{ + int val=randgroup[thread_id]; + + if(val*g_iRandKey>g_iMaxRandVal) + { + randgroup[thread_id]=128; + } + else + { + randgroup[thread_id]++; + } + *win= (unsigned short)(val+dip%g_iRandKey); + if(*win==0) *win=1; + *ipid=(unsigned short)(g_iMaxRandVal-val*g_iRandKey+sip%(*win)); + *ttl=(u_char)(val % 200 + 48); + + return; +} + +/* 2014-08-26 lijia add, ���ٱ�ϵͳ������RST��.*/ +static tcp_rst_finger_mark_t *make_tcp_rst_finger_mark(int thread_id, const raw_pkt_t *raw_pkt) +{ + tcp_rst_finger_mark_t *rst_finger; + const struct mesa_ip4_hdr *ip4_hdr; + + rst_finger = &g_tcp_rst_finger[thread_id]; + + ip4_hdr = (const struct mesa_ip4_hdr *)MESA_net_jump_to_layer(raw_pkt->raw_pkt_data, raw_pkt->low_layer_type, __ADDR_TYPE_IP_PAIR_V4); + if(NULL == ip4_hdr){ /* ������ */ + rst_finger->ip_id_host_order = (unsigned short)MESA_rand(); + rst_finger->ip_ttl = (unsigned short)MESA_rand_range(48, 127); + rst_finger->tcp_win_host_order = (unsigned short)MESA_rand_range(100, 1460); + }else{ + trick_algo_getrandval(thread_id, + ip4_hdr->ip_src.s_addr, /* 2015-10-27 lijia modify */ + ip4_hdr->ip_dst.s_addr, /* 2015-10-27 lijia modify */ + &rst_finger->ip_id_host_order, + &rst_finger->tcp_win_host_order, + &rst_finger->ip_ttl); + } + + return rst_finger; +} + + +/* + * Checksum stuff + */ +#define SENDPACKET_CKSUM_CARRY(x) \ + (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff)) + + +/* 2012-04-10 LiJia add, ��ȡ����IPv4��ַ +����: + device: �������� + ip_add: �洢IP��ַ��ָ�룬���Ϊ������. +����ֵ: + 0: ���� + -1:���� +*/ +int MESA_get_dev_ipv4(const char *device, int *ip_add) +{ + 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, SIOCGIFADDR, &ifr) == -1) + { + //perror("Cann't get ip addr:"); + goto err_exit; + } + + *ip_add = ((struct sockaddr_in*)&ifr.ifr_ifru.ifru_addr)->sin_addr.s_addr; + + close(fd); + + return 0; + +err_exit: + close(fd); + return -1; +} + +/* 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 MESA_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 MESA_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(u_int16_t *addr, int len) +{ + int sum; + int nleft; + u_int16_t ans; + u_int16_t *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 sendpacket_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); + } + + /* + * Dug Song came up with this very cool checksuming implementation + * eliminating the need for explicit psuedoheader use. Check it out. + */ + switch (protocol) + { + /* + * Style note: normally I don't advocate declaring variables inside + * blocks of control, but it makes good sense here. -- MDS + */ + case IPPROTO_TCP: + { + struct mesa_tcp_hdr *tcph_p = + (struct mesa_tcp_hdr *)(buf + ip_hl); + +#if (STUPID_SOLARIS_CHECKSUM_BUG) + tcph_p->th_sum = tcph_p->th_off << 2; + return (1); +#endif /* STUPID_SOLARIS_CHECKSUM_BUG */ + + tcph_p->th_sum = 0; + /* 2012-03-19 LiJia add, for IPv6 */ + if(is_ipv6) + { + sum = sendpacket_in_cksum((u_int16_t *)&ip6h_p->ip6_src, 32); + } + else + { + sum = sendpacket_in_cksum((u_int16_t *)&iph_p->ip_src, 8); + } + sum += ntohs(IPPROTO_TCP + len); + sum += sendpacket_in_cksum((u_int16_t *)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; + /* 2012-03-19 LiJia add, for IPv6 */ + if(is_ipv6) + { + sum = sendpacket_in_cksum((u_int16_t *)&ip6h_p->ip6_src, 32); + } + else + { + sum = sendpacket_in_cksum((u_int16_t *)&iph_p->ip_src, 8); + } + sum += ntohs(IPPROTO_UDP + len); + sum += sendpacket_in_cksum((u_int16_t *)udph_p, len); + udph_p->uh_sum = SENDPACKET_CKSUM_CARRY(sum); + break; + } + + case IPPROTO_IP: /* Dummy protocol for TCP. */ + { + iph_p->ip_sum = 0; + sum = sendpacket_in_cksum((u_int16_t *)iph_p, len); + iph_p->ip_sum = SENDPACKET_CKSUM_CARRY(sum); + break; + } + + case IPPROTO_ICMP: + { + struct mesa_icmp_hdr *icmph_p = + (struct mesa_icmp_hdr *)(buf + ip_hl); + + icmph_p->icmp_sum = 0; + sum = sendpacket_in_cksum((u_short *)icmph_p, len); + icmph_p->icmp_sum = SENDPACKET_CKSUM_CARRY(sum); + break; + } + + default: + { + return (-1); + } + } + return (1); +} + +int sendpacket_build_ipv4(u_int16_t carry_layer_len, u_int8_t tos, u_int16_t id, u_int16_t frag, + u_int8_t ttl, u_int8_t prot, u_int32_t src, u_int32_t 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){ + /* + * Unchecked runtime error for buf + IP_H + payload to be greater than + * the allocated heap memory. + */ + memcpy(buf + SENDPACKET_IP_H, payload, payload_s); + } + //memcpy((char *)buf, (char *)&ip_hdr, sizeof(ip_hdr)); + + return (0); +} + + +/* TODO: ����չͷ����IPv6�� */ +int sendpacket_build_ipv6(u_int8_t traffic_class, u_int32_t flow_lable, + u_int16_t len, u_int8_t next_header, u_int8_t 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) + { + /* + * Unchecked runtime error for buf + IP_H + payload to be greater than + * the allocated heap memory. + */ + memcpy(buf + sizeof(struct mesa_ip6_hdr), payload, payload_s); + } + + //memcpy(buf, &ip6_h, sizeof(struct mesa_ip6_hdr)); + + return 0; +} + +/* 2012-04-10 LiJia add, ���ڹ���ICMP-ECHO-REQUEST, ICMP-ECHO-REPLAY�� */ +int sendpacket_build_icmpv4_echo(u_int8_t type, u_int8_t code, u_int16_t sum, + u_int16_t id, u_int16_t seq, u_int8_t *payload, u_int32_t payload_s, unsigned char *buf) +{ + struct mesa_icmp_echo_hdr icmp_hdr; + + icmp_hdr.icmp_type = type; + icmp_hdr.icmp_code = code; + icmp_hdr.icmp_cksum = 0; /* checksum done in userland */ + icmp_hdr.icd_id = htons(id); + icmp_hdr.icd_seq = htons(seq); + + if(payload && payload_s){ + /* + * Unchecked runtime error for buf + IP_H + payload to be greater than + * the allocated heap memory. + */ + memcpy(buf + sizeof(struct mesa_icmp_echo_hdr), payload, payload_s); + } + + memcpy(buf, &icmp_hdr, sizeof(struct mesa_icmp_echo_hdr)); + + return 0; +} + + +int sendpacket_build_tcp(u_int16_t sp, u_int16_t dp, u_int32_t seq, u_int32_t ack, + u_int8_t th_flags, u_int16_t win, u_int16_t 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){ + /* + * Unchecked runtime error for buf + TCP_H + payload to be greater + * than the allocated heap memory. + */ + memcpy(buf + SENDPACKET_TCP_H, payload, payload_s); + } + //memcpy((char *)buf, (char *)&tcp_hdr, sizeof(tcp_hdr)); + + return (0); +} + +int sendpacket_build_tcp_with_option(u_int16_t sp, u_int16_t dp, u_int32_t seq, + u_int32_t ack, u_int8_t control,u_int16_t win, u_int16_t urg, + const char *option, int option_len, const char *payload, int payload_s, + unsigned char *buf) +{ + struct mesa_tcp_hdr tcp_hdr; + + if (!buf){ + return (-1); + } + if((option_len % 4) != 0){ + return (-2); + } + + 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 = control; /* control flags */ + tcp_hdr.th_x2 = 0; /* UNUSED */ + tcp_hdr.th_off = 5 + option_len/4; /* 20 byte header + option_len */ + 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(option && option_len){ + memcpy(buf + SENDPACKET_TCP_H, option, option_len); + } + + if (payload && payload_s){ + /* + * Unchecked runtime error for buf + TCP_H + payload to be greater + * than the allocated heap memory. + */ + memcpy(buf + SENDPACKET_TCP_H + option_len, payload, payload_s); + } + memcpy((char *)buf, (char *)&tcp_hdr, sizeof(struct mesa_tcp_hdr)); + return (0); +} + +int sendpacket_build_udp(u_int16_t sp, u_int16_t dp, const char *payload, int payload_s, + unsigned char *buf) +{ + struct mesa_udp_hdr udp_hdr; + + if (!buf) + { + return (-1); + } + + udp_hdr.uh_sport = htons(sp); /* source port */ + udp_hdr.uh_dport = htons(dp); /* destination port */ + udp_hdr.uh_ulen = htons(SENDPACKET_UDP_H + payload_s); /* total length */ + udp_hdr.uh_sum = 0; /* checksum */ + + if (payload && payload_s) + { + /* + * Unchecked runtime error for buf + UDP_H + payload to be greater + * than the allocated heap memory. + */ + memcpy(buf + SENDPACKET_UDP_H, payload, payload_s); + } + memcpy(buf, &udp_hdr, sizeof(udp_hdr)); + return (1); +} + +/* lijia add carry_layer_len args, + ��Ƕ�ס�����ģʽ�¹������ݰ�, û��payload, ��ʵ�ʻ����ϲ�Э��, ��teredo, ��Э��ʱʹ��. +*/ +int sendpacket_build_udp_dual_stack(u_int16_t sp, u_int16_t dp, const char *payload, + int payload_s, int carry_layer_len, unsigned char *buf) +{ + struct mesa_udp_hdr *udp_hdr; + + if (!buf){ + return (-1); + } + + udp_hdr = (struct mesa_udp_hdr *)buf; + + udp_hdr->uh_sport = htons(sp); /* source port */ + udp_hdr->uh_dport = htons(dp); /* destination port */ + udp_hdr->uh_ulen = htons(SENDPACKET_UDP_H + carry_layer_len); /* total length */ + udp_hdr->uh_sum = 0; /* checksum */ + + if (payload && payload_s){ + /* + * Unchecked runtime error for buf + UDP_H + payload to be greater + * than the allocated heap memory. + */ + memcpy(buf + SENDPACKET_UDP_H, payload, payload_s); + } + //memcpy(buf, &udp_hdr, sizeof(udp_hdr)); + return (0); +} + +int sendpacket_build_arp(u_short hrd, u_short pro, u_char hln, u_char pln, u_short op, + u_char *sha, u_char *spa, u_char *tha, u_char *tpa, + const u_char *payload, int payload_s, u_char *buf) +{ + struct mesa_arp_hdr arp_hdr; + + if (!buf){ + return (-1); + } + + arp_hdr.ar_hrd = htons(hrd); /* hardware address type */ + arp_hdr.ar_pro = htons(pro); /* protocol address type */ + arp_hdr.ar_hln = hln; /* hardware address length */ + arp_hdr.ar_pln = pln; /* protocol address length */ + arp_hdr.ar_op = htons(op); /* opcode command */ + memcpy(arp_hdr.ar_sha, sha, hln); /* sender hardware address */ + memcpy(arp_hdr.ar_spa, spa, pln); /* sender protocol (IP) address */ + memcpy(arp_hdr.ar_tha, tha, hln); /* target hardware address */ + memcpy(arp_hdr.ar_tpa, tpa, pln); /* target protocol (IP) address */ + + if (payload && payload_s){ + /* + * Unchecked runtime error for buf + LIBNET_ARP_H payload to be + * greater than the allocated heap memory. + */ + memcpy(buf + SENDPACKET_ARP_H, payload, payload_s); + } + memcpy(buf, &arp_hdr, sizeof(arp_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 sendpacket_build_ethernet(u_char *dst, u_char *src, u_short type, + const u_char *payload, int payload_s, u_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) + { + /* + * Unchecked runtime error for buf + ETH_H payload to be greater than + * the allocated heap memory. + */ + memcpy(buf + SENDPACKET_ETH_H, payload, payload_s); + } + memcpy(buf, ð_hdr, sizeof(eth_hdr)); + return (0); +} + +#if 0 +static int __do_kill_tcp(sendpacketTool *pSend, int thread_num, char CtoS_dir, char StoC_dir, + u_int32_t sip,ushort sid,ushort sport,u_int32_t sseq,u_int32_t sack, + u_int32_t dip,ushort did,ushort dport,u_int32_t dseq,u_int32_t dack) +{ + u_char sttl, dttl; + ushort swin, dwin, nouse; + int i, n_rst; + int sendnum=0; +#ifdef USE_TIME_TEST + struct timeval tv; + long begintime,endtime; + gettimeofday(&tv, 0); + begintime = tv.tv_sec* 1000*1000 + tv.tv_usec; + +#endif + + sip = htonl(sip); +#if 1 + dip = htonl(dip); +#else /* test */ + dip = htonl(0x0A00069A); +#endif + if((0 == rst_whom || 2 == rst_whom) && (0!=sseq)) { /* rst server */ + if(0 == sip || 0 == sport) return -1; + + //���ʹ�÷�������ôÿ����Ҫ���µõ������� + if(g_UseSendpktCard) + { + pSend->send_buf=(char *)getbuffrompag(thread_num); + } + + //if(0 != param->n_rst) n_rst = param->n_rst; + //else n_rst=num_of_rst_tos_send; + n_rst = num_of_rst_to_send; + for(i = 0; i < n_rst; i ++) + { + getrandval(thread_num,sip,dip,&nouse,&swin,&sttl); + if(-1 == sendpacket_build_ip(SENDPACKET_TCP_H, 0, sid, 0x4000, sttl, + IPPROTO_TCP, sip, dip, NULL, 0, pSend->send_buf)) + { + pSend->errflag=SEND_PACKET_IP_ERR; + return -1; + } + if(-1 == sendpacket_build_tcp(sport,dport,sseq,sack, + TH_RST|TH_ACK, swin, 0,NULL, 0, + pSend->send_buf + SENDPACKET_IP_H)) + { + pSend->errflag=SEND_PACKET_TCP_ERR; + return -1; + } + if(-1 == sendpacket_do_checksum(pSend->send_buf, + IPPROTO_TCP, SENDPACKET_TCP_H)) + { + pSend->errflag=SEND_PACKET_CHECKSUM_ERR; + return -1; + } + sendpacket_do_checksum(pSend->send_buf, IPPROTO_IP, SENDPACKET_IP_H); + pSend->send_buf_location = 1; + pSend->send_ptr = pSend->send_buf; + sendnum=sendpacket_write_new(pSend, SENDPACKET_TCP_H + SENDPACKET_IP_H, CtoS_dir); + if(sendnum==-1) + { + return -1; + } + + g_OutInfo.rstnum[thread_num]++; + sseq += 1460 * (i + 1); + //���ʹ�����»�û����� + if(g_UseSendpktCard) + { + if(i<n_rst-1) + pSend->send_buf=(char *)regetbuffrompag(thread_num,pSend->send_buf,0,SENDPACKET_IP_H); + } + } + //���ʹ�÷�������ôÿ����Ҫ���µõ������� + if(g_UseSendpktCard) + { + pag_freesendbuf(thread_num); + } + + } + if ((0 == rst_whom || 1 == rst_whom)&&(0!=dseq)) { /* rst client */ + if(0 == dip || 0 == dport) return -1; + //���ʹ�÷�������ôÿ����Ҫ���µõ������� + if(g_UseSendpktCard) + { + pSend->send_buf=(char *)getbuffrompag(thread_num); + } + + + //if(0 != param->n_rst) n_rst = param->n_rst; + //else n_rst=num_of_rst_toc_send; + n_rst = num_of_rst_to_send; + for(i = 0; i < n_rst; i ++) { + + getrandval(thread_num,sip,dip,&nouse,&dwin,&dttl); + + if(-1 == sendpacket_build_ip(SENDPACKET_TCP_H, 0, did, 0x4000, dttl, + IPPROTO_TCP, dip, sip, NULL, 0, pSend->send_buf)) + { + pSend->errflag=SEND_PACKET_IP_ERR; + return -1; + } + if(-1 == sendpacket_build_tcp(dport,sport,dseq,dack, + TH_RST|TH_ACK, dwin, 0, NULL, 0, + pSend->send_buf + SENDPACKET_IP_H)) + { + pSend->errflag=SEND_PACKET_TCP_ERR; + return -1; + } + if(-1 == sendpacket_do_checksum(pSend->send_buf, + IPPROTO_TCP, SENDPACKET_TCP_H)) + { + pSend->errflag=SEND_PACKET_CHECKSUM_ERR; + return -1; + } + sendpacket_do_checksum(pSend->send_buf, IPPROTO_IP, SENDPACKET_IP_H); + + pSend->send_buf_location = 1; + pSend->send_ptr = pSend->send_buf; + sendnum=sendpacket_write_new(pSend, SENDPACKET_TCP_H + SENDPACKET_IP_H, StoC_dir); + if(sendnum==-1) + { + return -1; + } + + g_OutInfo.rstnum[thread_num]++; + dseq += 1460 * (i + 1); + //���ʹ��,���»�û����� + if(g_UseSendpktCard) + { + if(i<n_rst-1) + pSend->send_buf=(char *)regetbuffrompag(thread_num,pSend->send_buf,0,SENDPACKET_IP_H); + } + } + //���ʹ�÷�������ôÿ����Ҫ���µõ������� + if(g_UseSendpktCard) + { + pag_freesendbuf(thread_num); + } + } + +#ifdef USE_TIME_TEST + gettimeofday(&tv, 0); + endtime = tv.tv_sec* 1000*1000 + tv.tv_usec; + killcount++; + killtime+=endtime-begintime; + if(killcount%10000==0) + { + fprintf(stderr,"killcount=%lu,average usetime is %lu\n",killcount,(killtime-oldtime)/10000); + MESA_runtime_log(RLOG_LV_INFO, "KILL TCP COUNT:", "killcount=%lu,average usetime is %lu\n",killcount,(killtime-oldtime)/10000); + oldtime=killtime; + } +#endif + return 0; +} + + +int MESA_kill_tcp(struct streaminfo *stream) +{ + u_int32_t sip, sseq, sack, dip, dseq, dack, payload; + u_int16_t sid, sport, did, dport; + struct tcphdr *thdr; + sendpacketTool *pTool; + unsigned char C2S_dir, S2C_dir; + + thdr = (struct tcphdr*)((u_int8_t *)a_packet + (a_packet->ip_hl << 2) ); + + payload = ntohs(a_packet->ip_len) - ((a_packet->ip_hl) << 2) - ((thdr->th_off) << 2); + if(0 != (TH_SYN & thdr->th_flags)) + payload ++; + + sip = ntohl((a_packet->ip_src).s_addr); + sseq = ntohl(thdr->th_seq) + payload; + sack = ntohl(thdr->th_ack); + dip = ntohl((a_packet->ip_dst).s_addr); + dseq = ntohl(thdr->th_ack); + dack = ntohl(thdr->th_seq) + payload; +#if 1 + sid = a_packet->ip_id; /* sender host byte order */ + did = 128; +#else /* test */ + sid = 0x1234; + did = 0xdddd; +#endif + + sport = ntohs(thdr->th_sport); + dport = ntohs(thdr->th_dport); + + pTool = &g_SendPacketTools[stream->threadnum]; + + if(1 == stream->curdir) + { + C2S_dir = stream->routedir; + S2C_dir = stream->routedir ^ 0x80; + } + else + { + S2C_dir = stream->routedir; + C2S_dir = stream->routedir ^ 0x80; + } + + return __do_kill_tcp(pTool, stream->threadnum, (char)C2S_dir, (char)S2C_dir, + sip, sid, sport, sseq, sack, + dip, did, dport, dseq, dack); +} +#endif + +/* + 1-�������а�ͷ�ij���, ����Ԥ���ռ�. ���㵽��ײ�Э��, �����MACҲ����MACͷ�ռ�; + 2-�ݹ�����л�ȡEthernet����ص�Э������. +*/ +static int calc_reserved_hdr_len(struct streaminfo *stream, int *net_layer_type) +{ + int reserved_hdr_len = 0; + + if(NULL == stream){ /* �ݹ�����ս�����! */ + return 0; + } + + if(is_proxy_stream(stream)){ /* �������ṹΪ����ṹ, ʵ�ʹ����ʱ���������� */ + reserved_hdr_len = 0; + goto done; + } + + switch(stream->addr.addrtype){ + case ADDR_TYPE_IPV4: + /* 2015-12-30 lijia modify, IP�Ͷ˿�ͬʱ�洢�ڴ˽ṹ */ + if(STREAM_TYPE_TCP == stream->type){ + reserved_hdr_len = sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip4_hdr); + }else if (STREAM_TYPE_UDP == stream->type){ + reserved_hdr_len = sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip4_hdr); + }else{ + printf("addr type is tuple4v4, but stream type is not TCP or UDP!\n"); + sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: addr type is tuple4v4, but stream type is :%d, not TCP or UDP.\n", __FILE__, __LINE__, stream->type); + return -1; + //assert(0); + } + break; + + case ADDR_TYPE_IPV6: + /* 2015-12-30 lijia modify, IP�Ͷ˿�ͬʱ�洢�ڴ˽ṹ */ + if(STREAM_TYPE_TCP == stream->type){ + reserved_hdr_len = sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip6_hdr);; + }else if (STREAM_TYPE_UDP == stream->type){ + reserved_hdr_len = sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip6_hdr);; + }else{ + printf("addr type is tuple4v6, but stream type is not TCP or UDP!\n"); + sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: addr type is tuple4v6, but stream type is :%d, not TCP or UDP.\n", __FILE__, __LINE__, stream->type); + return -1; + //assert(0); + } + break; + + case ADDR_TYPE_VLAN: + reserved_hdr_len = VLAN_TAG_LEN; + break; + + case ADDR_TYPE_MAC: + reserved_hdr_len = sizeof(struct mesa_ethernet_hdr); + break; + + case ADDR_TYPE_ARP: + printf("Sendpacket use ARP!\n"); + sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Sendpacket use ARP.\n", __FILE__, __LINE__); + return -1; + //assert(0); + break; + + case ADDR_TYPE_GRE: + { + struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream; + reserved_hdr_len = calc_gre_hdr_len( + (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr)); + } + break; + + case ADDR_TYPE_MPLS: + reserved_hdr_len = sizeof(struct mesa_mpls_hdr); + break; + + case ADDR_TYPE_PPPOE_SES: + reserved_hdr_len = sizeof(struct mesa_pppoe_session_hdr); + break; + + case ADDR_TYPE_TCP: + /* to do, ������ʹ�ѡ��İ�, ���Һ�ԭʼ����һ���Ļ�, ��ô����? + ��Ԥ�����, Ȼ�����ʵ��ѡ���, ��memmove�ƶ��ѹ���ĸ���. + */ + reserved_hdr_len = sizeof(struct mesa_tcp_hdr); + break; + + case ADDR_TYPE_UDP: + reserved_hdr_len = sizeof(struct mesa_udp_hdr); + break; + + case ADDR_TYPE_L2TP: + { + struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream; + reserved_hdr_len = calc_l2tp_hdr_len( + (const struct l2tp_hdr_v2 *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr)); + } + break; + + case __ADDR_TYPE_IP_PAIR_V4: + /* to do, ��������ѡ��İ�, ��ô����? */ + reserved_hdr_len = sizeof(struct mesa_ip4_hdr); + break; + + case __ADDR_TYPE_IP_PAIR_V6: + /* to do, ��������ѡ��İ�, ��ô����? */ + reserved_hdr_len = sizeof(struct mesa_ip6_hdr); + break; + + case ADDR_TYPE_PPP: + assert(0); /* ���ٵ�����PPP��, ��L2TP, PPTP��Ϊһ�� */ + reserved_hdr_len = sizeof(struct mesa_ppp_hdr); + break; + + case ADDR_TYPE_PPTP: + { + struct streaminfo_private *stream_pr = (struct streaminfo_private *)stream; + reserved_hdr_len = calc_gre_hdr_len( + (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr)); + reserved_hdr_len += sizeof(struct mesa_ppp_hdr); /* plus ppp hdr */ + } + break; + + default: + /* to do */ + printf("calc_reserved_hdr_len(): Not support addrtype:%d\n", stream->addr.addrtype); + reserved_hdr_len = -1; + break; + } + + if(reserved_hdr_len < 0){ + return -1; + } + +#if 0 /* 2014-10-24 lijia modify, pag, ppf�Ȳ�����ʽ��IPv4��ʼ */ + if(stream->pfather && (ADDR_TYPE_MAC == stream->pfather->addr.addrtype)){ +#else + if(CAP_LEVEL_MAC == g_packet_io_cap_level) { + if(stream->pfather && (CAP_LEVEL_MAC == stream->pfather->addr.addrtype)){ + /* ��¼MAC��֮�ϵ�Э���ַ����, �������Ethernet->type�ֶ� */ + *net_layer_type = (int)stream->addr.addrtype; + } + }else{ + /* to do: + ����������Զ�������ethernet��, ����������vlan�Ȳ���һ�Ҫ������ô��? + */ + if(NULL == stream->pfather){ + if(g_packet_io_cap_level == stream->addr.addrtype){ + *net_layer_type = (int)stream->addr.addrtype; + } + if((CAP_LEVEL_IPV4 == g_packet_io_cap_level) + && (ADDR_TYPE_IPV4 == stream->addr.addrtype)){ + *net_layer_type = CAP_LEVEL_IPV4; + } + } + } +#endif + +done: + return reserved_hdr_len + calc_reserved_hdr_len(stream->pfather, net_layer_type); +} + +static void set_build_layer_ipv4_args(int thread_num, unsigned char ip_ttl, unsigned short ip_id_host_order) +{ + layer_args_t *thread_args; + bulid_layer_ipv4_args_t *build_ip4_args; + + thread_args = &g_build_pkt_args[thread_num]; + build_ip4_args = &g_build_ipv4_args[thread_num]; + + memset(build_ip4_args, 0, sizeof(bulid_layer_ipv4_args_t)); + build_ip4_args->ip_ttl = ip_ttl; + build_ip4_args->ip_id_host_order = ip_id_host_order; + + thread_args->layer_args[__ADDR_TYPE_IP_PAIR_V4] = build_ip4_args; + + return; +} + +static void set_build_layer_tcp_args( int thread_num,unsigned char tcp_flags, + unsigned short tcp_win_host_order, unsigned int tcp_seq) +{ + layer_args_t *thread_args; + bulid_layer_tcp_args_t *build_tcp_args; + + thread_args = &g_build_pkt_args[thread_num]; + build_tcp_args = &g_build_tcp_args[thread_num]; + + memset(build_tcp_args, 0, sizeof(bulid_layer_tcp_args_t)); + build_tcp_args->tcp_flags = tcp_flags; + build_tcp_args->tcp_win_host_order = tcp_win_host_order; + build_tcp_args->tcp_seq = tcp_seq; + + thread_args->layer_args[ADDR_TYPE_TCP] = build_tcp_args; + + return; +} + +static inline void detach_build_layer_ipv4_args(int thread_num) +{ + g_build_pkt_args[thread_num].layer_args[__ADDR_TYPE_IP_PAIR_V4] = NULL; +} + +static inline void detach_build_layer_ipv6_args(int thread_num) +{ + g_build_pkt_args[thread_num].layer_args[__ADDR_TYPE_IP_PAIR_V6] = NULL; +} + +static inline void detach_build_layer_tcp_args(int thread_num) +{ + g_build_pkt_args[thread_num].layer_args[ADDR_TYPE_TCP] = NULL; +} + +#if 0 +static int __get_tcp_network_addr(struct streaminfo *stream, void *src_addr, void *dst_addr) +{ + struct streaminfo *father = stream->pfather; + int f_addr_type = __ADDR_TYPE_INIT; + + if(NULL == father){ + return f_addr_type; + } + + if(ADDR_TYPE_IPV4 == father->addr.addrtype){ + struct stream_tuple4_v4 *t4 = father->addr.tuple4_v4; + memcpy(src_addr, &t4->saddr, sizeof(int)); + memcpy(dst_addr, &t4->daddr, sizeof(int)); + f_addr_type = ADDR_TYPE_IPV4; + }else if(__ADDR_TYPE_IP_PAIR_V6 == father->addr.addrtype){ + struct stream_tuple4_v6 *t6 = father->addr.tuple4_v6; + memcpy(src_addr, &t6->saddr, IPV6_ADDR_LEN); + memcpy(dst_addr, &t6->daddr, IPV6_ADDR_LEN); + f_addr_type = __ADDR_TYPE_IP_PAIR_V6; + }else{ + ; + } + + return f_addr_type; +} +#endif + +static int build_net_layer_tcp(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_tcp_hdr *raw_tcp_hdr; + struct tcpdetail *a_tcp = (struct tcpdetail *)(stream_pr->stream_public.pdetail); + UINT16 tcp_win, tcp_flags; + UINT32 tcp_seq; + int tcp_data_len = a_tcp->datalen; + bulid_layer_tcp_args_t *build_tcp_args; + +#if 0 /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ�� */ + raw_tcp_hdr = (struct mesa_tcp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); +#else + raw_tcp_hdr = (struct mesa_tcp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + stream_pr->offset_to_ip_hdr + (char *)raw_pkt->raw_pkt_data); +#endif + + build_tcp_args = (bulid_layer_tcp_args_t *)g_build_pkt_args[stream_pr->stream_public.threadnum].layer_args[ADDR_TYPE_TCP]; + + if(raw_tcp_hdr->th_flags & TH_SYN){ + tcp_data_len++; + } + + if(NULL == build_tcp_args){ + tcp_flags = TH_ACK; + tcp_win = (UINT16)MESA_rand_range(1000, 1460); + tcp_seq = (UINT32)MESA_rand(); + }else{ + tcp_flags = build_tcp_args->tcp_flags; + tcp_win = build_tcp_args->tcp_win_host_order; + if(0 == build_tcp_args->tcp_seq){ + if(reverse){ + tcp_seq = ntohl(raw_tcp_hdr->th_ack); + }else{ + tcp_seq = ntohl(raw_tcp_hdr->th_seq)+tcp_data_len; + } + }else{ + tcp_seq = build_tcp_args->tcp_seq; + } + } + + if(reverse){ + sendpacket_build_tcp(ntohs(raw_tcp_hdr->th_dport), + ntohs(raw_tcp_hdr->th_sport), + tcp_seq, + ntohl(raw_tcp_hdr->th_seq)+tcp_data_len, + tcp_flags, + tcp_win, + 0, + NULL, + 0, + (unsigned char *)buf); + }else{ + sendpacket_build_tcp(ntohs(raw_tcp_hdr->th_sport), + ntohs(raw_tcp_hdr->th_dport), + tcp_seq, + ntohl(raw_tcp_hdr->th_ack), + tcp_flags, + tcp_win, + 0, + NULL, + 0, + (unsigned char *)buf); + } + + return sizeof(struct mesa_tcp_hdr); +} + +static int build_net_layer_udp(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_udp_hdr *raw_udp_hdr; + +#if 0 + raw_udp_hdr = (struct mesa_udp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); +#else + raw_udp_hdr = (struct mesa_udp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + stream_pr->offset_to_ip_hdr + (char *)raw_pkt->raw_pkt_data); +#endif + + if(reverse){ + sendpacket_build_udp_dual_stack(ntohs(raw_udp_hdr->uh_dport), + ntohs(raw_udp_hdr->uh_sport), + NULL, + 0, + carry_layer_len, + buf); + }else{ + sendpacket_build_udp_dual_stack(ntohs(raw_udp_hdr->uh_sport), + ntohs(raw_udp_hdr->uh_dport), + NULL, + 0, + carry_layer_len, + buf); + } + + return sizeof(struct mesa_udp_hdr); +} + + +static int build_net_layer_ipv4(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_ip4_hdr *raw_ip4_hdr; + UINT16 ip_id; + UINT8 ip_ttl; + bulid_layer_ipv4_args_t *build_ip4_args; + + raw_ip4_hdr = (struct mesa_ip4_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + build_ip4_args = (bulid_layer_ipv4_args_t *)g_build_pkt_args[stream_pr->stream_public.threadnum].layer_args[__ADDR_TYPE_IP_PAIR_V4]; + + if(NULL == build_ip4_args){ + ip_id = (UINT16)MESA_rand(); + ip_ttl = (UINT8)MESA_rand_range(48, 127); + }else{ + ip_id = build_ip4_args->ip_id_host_order; + ip_ttl = build_ip4_args->ip_ttl; + } + + if(reverse){ + sendpacket_build_ipv4(carry_layer_len, + 0, + ip_id, + IP_DF, + ip_ttl, + net_layer_to_ipv4_protocol(carry_layer_type), + raw_ip4_hdr->ip_dst.s_addr, + raw_ip4_hdr->ip_src.s_addr, + NULL, + 0, + (unsigned char *)buf); + }else{ + sendpacket_build_ipv4(carry_layer_len, + 0, + ip_id, + IP_DF, + ip_ttl, + net_layer_to_ipv4_protocol(carry_layer_type), + raw_ip4_hdr->ip_src.s_addr, + raw_ip4_hdr->ip_dst.s_addr, + NULL, + 0, + (unsigned char *)buf); + } + + sendpacket_do_checksum(buf, IPPROTO_IP, sizeof(struct mesa_ip4_hdr)); + + return sizeof(struct mesa_ip4_hdr); +} + +static int build_net_layer_ipv6(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_ip6_hdr *raw_ip6_hdr; + UINT8 hop = (UINT8)MESA_rand_range(64, 128); + + if(0 == g_packet_io_ipv6_switch){ + printf("IPv6 module is not support! Please set 'IPv6_module_enable=1' in main.conf.\n"); + return -1; + } + + raw_ip6_hdr = (struct mesa_ip6_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + + if(reverse){ + sendpacket_build_ipv6(0, + 0, + carry_layer_len, + net_layer_to_ipv6_protocol(carry_layer_type), + hop, + &raw_ip6_hdr->ip6_dst, + &raw_ip6_hdr->ip6_src, + NULL, + 0, + (unsigned char *)buf); + }else{ + sendpacket_build_ipv6(0, + 0, + carry_layer_len, + net_layer_to_ipv6_protocol(carry_layer_type), + hop, + &raw_ip6_hdr->ip6_src, + &raw_ip6_hdr->ip6_dst, + NULL, + 0, + (unsigned char *)buf); + } + + return sizeof(struct mesa_ip6_hdr); +} + +static int build_net_layer_pppoe_ses(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_pppoe_session_hdr *raw_hdr; + struct mesa_pppoe_session_hdr *send_hdr = (struct mesa_pppoe_session_hdr *)buf; + + raw_hdr = (struct mesa_pppoe_session_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + + /* PPPOE������, ��ԭʼ����copy���� */ + (void)reverse; + memcpy(send_hdr, raw_hdr, sizeof(struct mesa_pppoe_session_hdr)); + + /* lijia comment: + �˴�Ϊ��Ҫ��sizeof(send_hdr->ppp_protocol)? + ��ΪPPPOE_SES��ͷ�����Dz���PPPЭ�������ֶε�, ��Ϊ�˷��㴦��, ������2��1��. + */ + send_hdr->len = htons(carry_layer_len + sizeof(send_hdr->ppp_protocol)); + + return sizeof(struct mesa_pppoe_session_hdr); +} + +static int build_net_layer_vlan(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_vlan_hdr *raw_hdr; + struct mesa_vlan_hdr *send_hdr = (struct mesa_vlan_hdr *)buf; + + raw_hdr = (struct mesa_vlan_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + + /* VLAN������, ��ԭʼ����copy���� */ + (void)reverse; + memcpy(send_hdr, raw_hdr, sizeof(struct mesa_vlan_hdr)); + + return sizeof(struct mesa_vlan_hdr); +} + +static int build_net_layer_gerv0_exthdr(const struct mesa_gre_hdr *parsed_hdr, struct mesa_gre_hdr *send_hdr) +{ + const struct mesa_gre_extend_hdr *parsed_ext_hdr = (const struct mesa_gre_extend_hdr *)&parsed_hdr->gre_extend; + char *send_ext_value = (char *)&send_hdr->gre_extend; + + + if(parsed_hdr->gre_base.checksum_flag != 0){ + memcpy(send_ext_value, &parsed_ext_hdr->checksum, sizeof(short)); + send_ext_value += sizeof(short); + memcpy(send_ext_value, &parsed_ext_hdr->offset, sizeof(short)); + send_ext_value += sizeof(short); + } + + if(parsed_hdr->gre_base.key_flag != 0){ + memcpy(send_ext_value, &parsed_ext_hdr->key, sizeof(int)); + send_ext_value += sizeof(int); + } + + if(parsed_hdr->gre_base.seq_flag != 0){ + unsigned tmp_int = htons(ntohs(parsed_ext_hdr->seq_num) + 1); /* seq + 1 */ + memcpy(send_ext_value, &tmp_int, sizeof(int)); + send_ext_value += sizeof(int); + } + + return 0; +} + +static int build_net_layer_gerv1_exthdr(const struct mesa_gre_hdr *parsed_hdr, + struct mesa_gre_hdr *send_hdr, int carry_layer_len, UINT16 send_call_id, int reverse) +{ + const struct mesa_gre_base_hdr_v1*parsed_base_hdr = (const struct mesa_gre_base_hdr_v1*)&parsed_hdr->gre_base; + const struct mesa_gre_extend_hdr *parsed_ext_hdr = (const struct mesa_gre_extend_hdr *)&parsed_hdr->gre_extend; + char *send_ext_value = (char *)&(send_hdr->gre_extend); + struct mesa_gre_base_hdr_v1 *send_grev1_hdr = (struct mesa_gre_base_hdr_v1 *)send_hdr; + + unsigned short payload_len = (unsigned short)carry_layer_len; + payload_len = htons(payload_len); + + memcpy(send_ext_value, &payload_len, sizeof(short)); /* GREv1 �ض���length�ֶ� */ + send_ext_value += sizeof(short); + + memcpy(send_ext_value, &send_call_id, sizeof(short)); /* GREv1 �ض���callid�ֶ� */ + send_ext_value += sizeof(short); + + if(0 == reverse){ + if(parsed_base_hdr->seq_flag != 0){ + unsigned tmp_int = htonl(ntohl(parsed_ext_hdr->seq_num) + 1); /* seq + 1 */ + memcpy(send_ext_value, &tmp_int, sizeof(int)); + send_ext_value += sizeof(int); + send_grev1_hdr->seq_flag = 1; + }else{ + send_grev1_hdr->seq_flag = 0; + } + + if(parsed_base_hdr->ack_flag != 0){ + memcpy(send_ext_value, &parsed_ext_hdr->ack_num, sizeof(int)); + send_ext_value += sizeof(int); + send_grev1_hdr->ack_flag = 1; + }else{ + send_grev1_hdr->ack_flag = 0; + } + }else{ + if(parsed_base_hdr->ack_flag != 0){ + unsigned tmp_int = htonl(ntohl(parsed_ext_hdr->ack_num) + 1); /* seq = opposite_ack + 1 */ + memcpy(send_ext_value, &tmp_int, sizeof(int)); + send_ext_value += sizeof(int); + send_grev1_hdr->seq_flag = 1; + }else{ + send_grev1_hdr->seq_flag = 0; + } + + if(parsed_base_hdr->seq_flag != 0){ + memcpy(send_ext_value, &parsed_ext_hdr->seq_num, sizeof(int)); /* ack = opposite_seq */ + send_ext_value += sizeof(int); + send_grev1_hdr->ack_flag = 1; + }else{ + send_grev1_hdr->ack_flag = 0; + } + } + + return 0; +} + +static int build_net_layer_gre(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + const struct mesa_gre_hdr *raw_hdr; + struct mesa_gre_hdr stack_hdr; + struct mesa_gre_hdr *send_hdr = (struct mesa_gre_hdr *)buf; + int gre_hdr_len, ret; + const struct layer_addr_pptp *raw_pptp_addr = stream_pr->stream_public.addr.pptp; +#if 0 + /* NOTE: BUGFIX, ��ǰ����curdir���ܲ�û������, ��Ϊֻ��TCP��������curdir, ���Բ���ȡ��������curdirֵ */ + UCHAR curdir = stream_pr->stream_public.curdir; +#endif + UINT16 send_call_id; + + raw_hdr = (const struct mesa_gre_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + gre_hdr_len = set_gre_hdr(&stack_hdr, (const void *)raw_hdr); + if(gre_hdr_len < 0){ + return -1; + } + + if((reverse != 0) + && ((0 == raw_pptp_addr->C2S_call_id) || (0 == raw_pptp_addr->S2C_call_id))){ + /* ������һ������û�л�ȡ��callid, ����������� */ + sapp_runtime_log(20, "in gre layer, send dir is reverse, but haven't get opposite single stream info!\n"); + return -1; + } + + if(0 == reverse){ + if(stack_hdr.gre_extend.call_id == raw_pptp_addr->C2S_call_id){ + /* ͬ��, �͵�ǰ����һ�� */ + send_call_id = raw_pptp_addr->C2S_call_id; + }else{ + send_call_id = raw_pptp_addr->S2C_call_id; + } + }else{ + /* ����, ʹ�öԶ˵�callid */ + if(stack_hdr.gre_extend.call_id == raw_pptp_addr->C2S_call_id){ + send_call_id = raw_pptp_addr->S2C_call_id; + }else{ + send_call_id = raw_pptp_addr->C2S_call_id; + } + } + + memcpy(&send_hdr->gre_base, &raw_hdr->gre_base, sizeof(struct mesa_gre_base_hdr_v0)); + + if(0 == stack_hdr.gre_base.version){ + ret = build_net_layer_gerv0_exthdr(&stack_hdr, send_hdr); + }else if(1 == stack_hdr.gre_base.version){ + ret = build_net_layer_gerv1_exthdr(&stack_hdr, send_hdr, carry_layer_len, send_call_id, reverse); + }else{ + return -1; + } + + if(ret < 0){ + return -1; + } + + return gre_hdr_len; +} + +static int build_net_layer_mpls(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_mpls_hdr *raw_hdr; + + raw_hdr = (struct mesa_mpls_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + + /* MPLS������, ��ԭʼ����copy���� */ + (void)reverse; + memcpy(buf, raw_hdr, sizeof(struct mesa_mpls_hdr)); + + return sizeof(struct mesa_mpls_hdr); +} + +static void checksum_for_carry_layer(unsigned char *buf, int this_layer_type, int carry_layer_type, int payload_len) +{ + if((ADDR_TYPE_TCP != carry_layer_type) && (ADDR_TYPE_UDP != carry_layer_type)){ + return; + } + + if(__ADDR_TYPE_IP_PAIR_V4 == this_layer_type){ + sendpacket_do_checksum(buf, net_layer_to_ipv4_protocol(carry_layer_type), payload_len); + }else if(__ADDR_TYPE_IP_PAIR_V6 == this_layer_type){ + sendpacket_do_checksum(buf, net_layer_to_ipv6_protocol(carry_layer_type), payload_len); + }else{ + return; + } +} + +static int build_net_layer_ppp(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + struct mesa_ppp_hdr *raw_ppp_hdr; + + raw_ppp_hdr = (struct mesa_ppp_hdr *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + + /* PPP������, ��ԭʼ����copy���� */ + (void)reverse; + memcpy(buf, raw_ppp_hdr, sizeof(struct mesa_ppp_hdr)); + + return sizeof(struct mesa_ppp_hdr); +} + +static int build_net_layer_l2tp(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt, int l2tp_raw_hdr_len) +{ + const struct l2tp_hdr_v2 *raw_hdr; + const char *raw_hdr_ptr; + unsigned char *send_ptr = buf; + unsigned short int16_tmp; + + if(reverse != 0){ + /* TODO: + L2TP��c2s��s2c����TUNNEL-ID��һ��, Ŀǰû���γ�L2TP��, ��������һ���������Ϣ , + ����, ��ʱֻ�ܵ���KILL. + */ + return -1; + } + + raw_hdr = (const struct l2tp_hdr_v2 *)(stream_pr->offset_to_raw_pkt_hdr + (char *)raw_pkt->raw_pkt_data); + raw_hdr_ptr = (const char *)raw_hdr; + memcpy(send_ptr, raw_hdr, sizeof(struct l2tp_hdr_v2)); + send_ptr += sizeof(struct l2tp_hdr_v2); + raw_hdr_ptr += sizeof(struct l2tp_hdr_v2); + + if(raw_hdr->length_present){ + int16_tmp = carry_layer_len + l2tp_raw_hdr_len; + int16_tmp = ntohs(int16_tmp); + memcpy(send_ptr, &int16_tmp, sizeof(short)); + send_ptr += sizeof(short); + raw_hdr_ptr += sizeof(short); + } + + memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte tunnel id */ + send_ptr += sizeof(short); + raw_hdr_ptr += sizeof(short); + + memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte session id */ + send_ptr += sizeof(short); + raw_hdr_ptr += sizeof(short); + + if(raw_hdr->seq_present){ + memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte Ns */ + send_ptr += sizeof(short); + raw_hdr_ptr += sizeof(short); + + memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte Nr */ + send_ptr += sizeof(short); + raw_hdr_ptr += sizeof(short); + } + + if(raw_hdr->offset_present){ + int16_tmp = ntohs(*(unsigned short *)raw_hdr_ptr); /* offset size */ + memcpy(send_ptr, raw_hdr_ptr, sizeof(short)); /* 2 byte offset */ + send_ptr += sizeof(short); + raw_hdr_ptr += sizeof(short); + + memcpy(send_ptr, raw_hdr_ptr, int16_tmp); + send_ptr += int16_tmp; + raw_hdr_ptr += int16_tmp; + } + + return l2tp_raw_hdr_len; +} + +/* + buf: ִ��Ӧ�ò㸺�ص�ַ, skip hdr. + reverse: �����з����Եĵ�ַ, �跴��. +*/ +static int build_net_layer_pkt(struct streaminfo_private *stream_pr, int carry_layer_type, + int carry_layer_len, unsigned char *buf, int reverse, const raw_pkt_t *raw_pkt) +{ + int this_layer_len = 0, ret; + int transport_layer_len; + struct streaminfo *stream; + + if(NULL == stream_pr){ + return carry_layer_len; + } + + stream = &stream_pr->stream_public; + + if(is_proxy_stream(stream)){ /* �������ṹΪ����ṹ, ʵ�ʵİ������ڴ˲�, �����ʱ���������� */ + this_layer_len = 0; + goto done; + } + + switch(stream->addr.addrtype){ + case ADDR_TYPE_IPV4: + /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, �ȹ���TCP/UDP�� */ + if(STREAM_TYPE_TCP == stream->type){ + transport_layer_len = sizeof(struct mesa_tcp_hdr); + buf -= sizeof(struct mesa_tcp_hdr); + build_net_layer_tcp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_TCP; + }else{ + transport_layer_len = sizeof(struct mesa_udp_hdr); + buf -= sizeof(struct mesa_udp_hdr); + build_net_layer_udp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_UDP; + } + + /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, ��������IPv4�� */ + this_layer_len += sizeof(struct mesa_ip4_hdr) + transport_layer_len; + buf -= sizeof(struct mesa_ip4_hdr); + build_net_layer_ipv4(stream_pr, carry_layer_type, carry_layer_len + transport_layer_len, buf, reverse, raw_pkt); + + /* TCP��У�����ҪIP��ַ��Ϣ, ����Ҫ�ڹ�����IP����Ϣ��, �ټ���checksum */ + checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V4, carry_layer_type, carry_layer_len+transport_layer_len); + carry_layer_type = __ADDR_TYPE_IP_PAIR_V4; + + break; + + case ADDR_TYPE_IPV6: + /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, �ȹ���TCP/UDP�� */ + if(STREAM_TYPE_TCP == stream->type){ + transport_layer_len = sizeof(struct mesa_tcp_hdr); + buf -= sizeof(struct mesa_tcp_hdr); + build_net_layer_tcp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_TCP; + }else{ + transport_layer_len = sizeof(struct mesa_udp_hdr); + buf -= sizeof(struct mesa_udp_hdr); + build_net_layer_udp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_UDP; + } + + /* 2015-12-30 lijia modify, IP�Ͷ˿ڴ洢��һ���ṹ, ��������IPv6�� */ + this_layer_len += sizeof(struct mesa_ip6_hdr) + transport_layer_len; + buf -= sizeof(struct mesa_ip6_hdr); + build_net_layer_ipv6(stream_pr, carry_layer_type, carry_layer_len + transport_layer_len, buf, reverse, raw_pkt); + + /* TCP��У�����ҪIP��ַ��Ϣ, ����Ҫ�ڹ�����IP����Ϣ��, �ټ���checksum */ + checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V6, carry_layer_type, carry_layer_len+transport_layer_len); + carry_layer_type = __ADDR_TYPE_IP_PAIR_V6; + break; + + case __ADDR_TYPE_IP_PAIR_V4: + /* to do, ��������ѡ��İ�, ��ô����? */ + this_layer_len = sizeof(struct mesa_ip4_hdr); + buf -= sizeof(struct mesa_ip4_hdr); + build_net_layer_ipv4(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + + /* TCP��У�����ҪIP��ַ��Ϣ, ����Ҫ�ڹ�����IP����Ϣ��, �ټ���checksum */ + checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V4, carry_layer_type, carry_layer_len); + carry_layer_type = __ADDR_TYPE_IP_PAIR_V4; + break; + + case __ADDR_TYPE_IP_PAIR_V6: + this_layer_len = sizeof(struct mesa_ip6_hdr); + buf -= sizeof(struct mesa_ip6_hdr); + build_net_layer_ipv6(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + checksum_for_carry_layer(buf, __ADDR_TYPE_IP_PAIR_V6, carry_layer_type, carry_layer_len); + carry_layer_type = __ADDR_TYPE_IP_PAIR_V6; + break; + + case ADDR_TYPE_VLAN: + this_layer_len = VLAN_TAG_LEN; + buf -= sizeof(struct mesa_vlan_hdr); + build_net_layer_vlan(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_VLAN; + break; + + case ADDR_TYPE_MAC: + this_layer_len = 0; + //this_layer_len = build_net_layer_ethernet(stream, payload, payload_len, buf, reverse, net_layer); + //net_layer = NET_LAYER_ETHERNET; + /* ����ģʽ��, ����ֱ�ӿ�ϵͳsendto����, ����MAC��ַ����buildϵ�к���������, ��dl_io����� */ + return carry_layer_len; + break; + + /* TODO: GRE v1��callid, �ֱ�洢��C2S, S2C������������ݰ�, ����˫��RST��Ҫ��¼��һ�����ֵ */ + case ADDR_TYPE_GRE: + this_layer_len = calc_gre_hdr_len( + (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr)); + buf -= this_layer_len; + ret = build_net_layer_gre(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + if(ret < 0){ + return -1; + } + carry_layer_type = ADDR_TYPE_GRE; + break; + + case ADDR_TYPE_MPLS: + this_layer_len = sizeof(struct mesa_mpls_hdr); + buf -= sizeof(struct mesa_mpls_hdr); + build_net_layer_mpls(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_MPLS; + break; + + case ADDR_TYPE_PPPOE_SES: + this_layer_len = sizeof(struct mesa_pppoe_session_hdr); + buf -= sizeof(struct mesa_pppoe_session_hdr); + build_net_layer_pppoe_ses(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_PPPOE_SES; + break; + + case ADDR_TYPE_TCP: + /* to do, ��������ѡ��İ�, ��ô����? */ + this_layer_len = sizeof(struct mesa_tcp_hdr); + buf -= sizeof(struct mesa_tcp_hdr); + build_net_layer_tcp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_TCP; + break; + + case ADDR_TYPE_UDP: + this_layer_len = sizeof(struct mesa_udp_hdr); + buf -= sizeof(struct mesa_udp_hdr); + build_net_layer_udp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_UDP; + break; + + case ADDR_TYPE_L2TP: + this_layer_len = calc_l2tp_hdr_len( + (const struct l2tp_hdr_v2 *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr)); + if(this_layer_len < 0){ + return -1; + } + buf -= this_layer_len; + ret = build_net_layer_l2tp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt, this_layer_len); + if(ret < 0){ + return -1; + } + carry_layer_type = ADDR_TYPE_L2TP; + break; + + case ADDR_TYPE_PPP: + assert(0); + this_layer_len = sizeof(struct mesa_ppp_hdr); + buf -= sizeof(struct mesa_ppp_hdr); + build_net_layer_ppp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + carry_layer_type = ADDR_TYPE_PPP; + break; + + case ADDR_TYPE_PPTP: + { + int gre_layer_len; + buf -= sizeof(struct mesa_ppp_hdr); + build_net_layer_ppp(stream_pr, carry_layer_type, carry_layer_len, buf, reverse, raw_pkt); + + gre_layer_len = calc_gre_hdr_len( + (const struct mesa_gre_hdr *)((const char *)stream_pr->raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr)); + + /* ֱ��copy pppͷ������ */ + memcpy(buf, (char *)raw_pkt->raw_pkt_data + stream_pr->offset_to_raw_pkt_hdr + gre_layer_len, sizeof(struct mesa_ppp_hdr)); + + buf -= gre_layer_len; + ret = build_net_layer_gre(stream_pr, ADDR_TYPE_PPP, carry_layer_len, buf, reverse, raw_pkt); + if(ret < 0){ + return -1; + } + carry_layer_type = ADDR_TYPE_GRE; + this_layer_len = gre_layer_len + sizeof(struct mesa_ppp_hdr); + } + break; + + default: + printf("build_net_layer_pkt(): unsupport protocol:%d! TODO!\n", stream->addr.addrtype); + goto err; + break; + } + +done: + return build_net_layer_pkt((struct streaminfo_private *)stream->pfather,carry_layer_type, + this_layer_len+carry_layer_len, + buf, reverse, raw_pkt); + +err: + return -1; +} + + +static int __do_kill_tcp(struct streaminfo *stream, const void *ext_raw_pkt, int kill_num, + char *feedback_buf, int *feedback_buf_len) +{ + int i, ret = -1, reserved_hdr_len, send_len = 0; + MESA_send_handle *send_handle; + int thread_num = stream->threadnum; + int low_net_layer_type = -1; + tcp_rst_finger_mark_t *tcp_rst_finger; + const raw_pkt_t *raw_pkt = NULL; + struct streaminfo_private *stream_pr; + + (void)ext_raw_pkt; + + if(NULL == stream){ + return -1; + } + + stream_pr = (struct streaminfo_private *)stream; + send_handle = &g_send_handle[thread_num]; + + /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ(����֮ǰpappƽ̨), ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */ + raw_pkt = (const raw_pkt_t *)stream_pr->raw_pkt; + + if((NULL == raw_pkt) || (RAW_PKT_MAGIC_NUM != raw_pkt->magic_num)){ + return -1; + } + + reserved_hdr_len = calc_reserved_hdr_len(stream, &low_net_layer_type); + if((reserved_hdr_len < 0) || (-1 == low_net_layer_type)){ + sapp_runtime_log(RLOG_LV_INFO, "%s:%d: MESA_kill_tcp() calc_reserved_hdr_len error !", __FILE__, __LINE__); + ret = -1; + goto fun_exit; + } + + tcp_rst_finger = make_tcp_rst_finger_mark(thread_num, (const raw_pkt_t *)raw_pkt); + set_build_layer_ipv4_args(thread_num, tcp_rst_finger->ip_ttl, tcp_rst_finger->ip_id_host_order); + set_build_layer_tcp_args(thread_num, TH_RST|TH_ACK, tcp_rst_finger->tcp_win_host_order, 0); + + for(i = 0; i < kill_num; i++){ + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + + send_len = build_net_layer_pkt(stream_pr, ADDR_TYPE_TCP, 0, send_handle->send_buf + reserved_hdr_len, 0, raw_pkt); + if(send_len < 0){ + ret = -1; + goto fun_exit; + } + ret = packet_io_send(send_handle, reserved_hdr_len, SEND_TYPE_LINK_INJECT, + low_net_layer_type, stream->routedir, thread_num, + feedback_buf, feedback_buf_len); + if(ret < 0){ + send_handle->tot_send_err++; + }else{ + send_handle->tot_send_pkt++; + send_handle->tot_send_byte += send_len; + } + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + + g_SysInputInfo[thread_num][SEND_TCP_RST]++; + g_SysInputInfo[thread_num][SEND_TCP_RST_LEN]+=send_len; + + /* ����ģʽ��, �����������һ��, �ܼ�����, + �������ȷ�C2S���Ρ��ٷ�S2C����, + ��ֹ��RST����ʱ����, ��һ���ٳ�û�а�; + */ +#if 0 + } + + for(i = 0; i < KILL_TCP_RST_NUM; i++){ +#endif + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + send_len = build_net_layer_pkt(stream_pr, ADDR_TYPE_TCP, 0, send_handle->send_buf + reserved_hdr_len, 1, raw_pkt); + if(send_len < 0){ + ret = -1; + goto fun_exit; + break; + } + ret = packet_io_send(send_handle, reserved_hdr_len, SEND_TYPE_LINK_INJECT, + low_net_layer_type, stream->routedir ^ 1, thread_num, + feedback_buf, feedback_buf_len); + if(ret < 0){ + send_handle->tot_send_err++; + }else{ + send_handle->tot_send_pkt++; + send_handle->tot_send_byte += send_len; + } + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + g_SysInputInfo[thread_num][SEND_TCP_RST]++; + g_SysInputInfo[thread_num][SEND_TCP_RST_LEN]+=send_len; + } + +fun_exit: + + detach_build_layer_ipv4_args(thread_num); + detach_build_layer_tcp_args(thread_num); + + stream_pr->stream_killed_flag = 1; + + return ret; +} + + + +/* + LiJia note, to do: + �����Ϊ��������, 1,2,3,4,x,6, ��5��������, ��6����������, + �����6��������������Ϣ, ��Ҫkill_tcp, + ����5��������ʱ, streaminfo��洢�Ķ��ǵ�5��������Ϣ, + Ȼ���ٴ��������е�6����������, ��ʱ����kill_tcp, ��ز����Dz��Ե�, + ʵ�ʵ�seq��ackʹ�õ��ǵ�5������! + Ӧ��ʹ��buf_unorder�е�seq��ack, �����ǵ�ǰ����ԭʼ��. +*/ +int MESA_kill_tcp(struct streaminfo *stream, const void *ext_raw_pkt) +{ + /* �ⲿ����, ��һ��FD, ����KILL_TCP_RST_NUM��. */ + return __do_kill_tcp(stream, ext_raw_pkt, KILL_TCP_RST_NUM, (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); +} + +int MESA_kill_tcp_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len) +{ + if((NULL == feedback_buf) || (NULL == feedback_buf_len)){ + return -2; + } + if(*feedback_buf_len <= 0){ + return -2; + } + return __do_kill_tcp(stream, raw_pkt, KILL_TCP_RST_NUM, feedback_buf, feedback_buf_len); +} + +/* 2016-06-15 lijia add */ +int MESA_kill_tcp_remedy(struct streaminfo *stream, const void *ext_raw_pkt) +{ + /* FD����, ֻ����1��. */ + return __do_kill_tcp(stream, ext_raw_pkt, 1, (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); +} + +static int __do_kill_tcp_synack(struct streaminfo *stream, const void *ext_raw_pkt, + char *feedback_buf, int *feedback_buf_len) +{ + int i, ret, reserved_hdr_len, send_len = 0; + MESA_send_handle *send_handle; + int thread_num = stream->threadnum; + int low_net_layer_type; + tcp_rst_finger_mark_t *tcp_rst_finger; + const raw_pkt_t *raw_pkt = NULL; + struct streaminfo_private *stream_pr; + + (void)ext_raw_pkt; + + if(NULL == stream){ + return -1; + } + + stream_pr = (struct streaminfo_private *)stream; + send_handle = &g_send_handle[thread_num]; + raw_pkt = (const raw_pkt_t *)stream_pr->raw_pkt; + if((NULL == raw_pkt) || (RAW_PKT_MAGIC_NUM != raw_pkt->magic_num)){ + return -1; + } + + reserved_hdr_len = calc_reserved_hdr_len(stream, &low_net_layer_type); + if((reserved_hdr_len < 0) || (-1 == low_net_layer_type)){ + ret = -1; + goto fun_exit; + } + tcp_rst_finger = make_tcp_rst_finger_mark(thread_num, (const raw_pkt_t *)raw_pkt); + set_build_layer_ipv4_args(thread_num, tcp_rst_finger->ip_ttl, tcp_rst_finger->ip_id_host_order); + set_build_layer_tcp_args(thread_num, TH_SYN|TH_ACK, tcp_rst_finger->tcp_win_host_order, MESA_rand()); + + for(i = 0; i < KILL_TCP_SYN_ACK_NUM; i++){ + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + + send_len = build_net_layer_pkt(stream_pr, ADDR_TYPE_TCP, 0, send_handle->send_buf + reserved_hdr_len, 1, raw_pkt); + if(send_len < 0){ + ret = -1; + goto fun_exit; + } + ret = packet_io_send(send_handle, reserved_hdr_len, SEND_TYPE_LINK_INJECT, + low_net_layer_type, stream->routedir ^ 1, thread_num, + feedback_buf, feedback_buf_len); + if(ret < 0){ + send_handle->tot_send_err++; + }else{ + send_handle->tot_send_pkt++; + send_handle->tot_send_byte += send_len; + } + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + g_SysInputInfo[thread_num][SEND_TCP_SYN_ACK]++; + g_SysInputInfo[thread_num][SEND_TCP_SYN_ACK_LEN]+=send_len; + } +fun_exit: + detach_build_layer_ipv4_args(thread_num); + detach_build_layer_tcp_args(thread_num); + + stream_pr->stream_killed_flag = 1; + + return ret; +} + +int MESA_kill_tcp_synack(struct streaminfo *stream, const void *ext_raw_pkt) +{ + return __do_kill_tcp_synack(stream, ext_raw_pkt, (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); +} + +int MESA_kill_tcp_synack_feedback(struct streaminfo *stream, const void *ext_raw_pkt, + char *feedback_buf, int *feedback_buf_len) +{ + if((NULL == feedback_buf) || (NULL == feedback_buf_len)){ + return -2; + } + if(*feedback_buf_len <= 0){ + return -2; + } + + return __do_kill_tcp_synack(stream, ext_raw_pkt, feedback_buf, feedback_buf_len); +} + + +/* 2014-11-15 lijia add, for drop NO-TCP protocol in serial mode. + return value: + >= 0: success. + -1 : error. +*/ +int MESA_kill_connection(struct streaminfo *stream, const void *ext_raw_pkt) +{ + int ret; + struct streaminfo_private *stream_pr; + + (void)ext_raw_pkt; + + if(NULL == stream){ + return -1; + } + stream_pr = (struct streaminfo_private *)stream; + + switch(stream->type){ + case STREAM_TYPE_TCP: + //ret = MESA_kill_tcp(stream, ext_raw_pkt); + /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ, ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */ + ret = MESA_kill_tcp(stream, stream_pr->raw_pkt); + break; + case STREAM_TYPE_UDP: + stream_pr->stream_killed_flag = 1; + ret = 0; + break; + + case STREAM_TYPE_SOCKS4: + case STREAM_TYPE_SOCKS5: + case STREAM_TYPE_HTTP_PROXY: + case STREAM_TYPE_PPPOE: + //TODO + printf("stream type: %d, not support kill_connection!\n", stream->type); + return -1; + //assert(0); + break; + + default: + ret = -1; + break; + } + + return ret; +} + +int MESA_kill_connection_feedback(struct streaminfo *stream, const void *ext_raw_pkt, + char *feedback_buf, int *feedback_buf_len) +{ + int ret; + struct streaminfo_private *stream_pr; + + (void)ext_raw_pkt; + + if((NULL == feedback_buf) || (NULL == feedback_buf_len)){ + return -2; + } + if(*feedback_buf_len <= 0){ + return -2; + } + + if(NULL == stream){ + return -1; + } + stream_pr = (struct streaminfo_private *)stream; + + switch(stream->type){ + case STREAM_TYPE_TCP: + //ret = MESA_kill_tcp(stream, ext_raw_pkt); + /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ, ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */ + ret = MESA_kill_tcp_feedback(stream, stream_pr->raw_pkt, feedback_buf, feedback_buf_len); + break; + case STREAM_TYPE_UDP: + stream_pr->stream_killed_flag = 1; + ret = 0; + break; + + case STREAM_TYPE_SOCKS4: + case STREAM_TYPE_SOCKS5: + case STREAM_TYPE_HTTP_PROXY: + case STREAM_TYPE_PPPOE: + //TODO + printf("stream type: %d, not support kill_connection!\n", stream->type); + return -1; + //assert(0); + break; + + default: + ret = -1; + break; + } + + return ret; +} + +static int __do_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len, + const void *ext_raw_pkt, UCHAR snd_routedir, + char *feedback_buf, int *feedback_buf_len) +{ + int ret = -1, reserved_hdr_len, send_len = 0; + MESA_send_handle *send_handle; + int thread_num = stream->threadnum; + int low_net_layer_type; + int snd_dir_reverse; + const raw_pkt_t *raw_pkt; + struct streaminfo_private *stream_pr; + + (void)ext_raw_pkt; + + if(NULL == stream){ + return -1; + } + + if(dir_check(snd_routedir) < 0){ + return -1; + } + + stream_pr = (struct streaminfo_private *)stream; + /* ��ı���ijЩ�ص�������ԭʼ������ΪIP��ͷ, ���Բ���Ҫ�������ԭʼ��, ��Ϣ���洢��˽�����ṹ���� */ + raw_pkt = (const raw_pkt_t *)stream_pr->raw_pkt; + if((NULL == raw_pkt) || (RAW_PKT_MAGIC_NUM != raw_pkt->magic_num)){ + return -1; + } + + snd_dir_reverse = ((snd_routedir == stream->routedir) ? 0: 1); + + send_handle = &g_send_handle[thread_num]; + + reserved_hdr_len = calc_reserved_hdr_len(stream, &low_net_layer_type); + if((reserved_hdr_len < 0) || (-1 == low_net_layer_type)){ + ret = -1; + goto fun_exit; + } + + if(payload_len + reserved_hdr_len > MTU_MAX){ + sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: MESA_inject_pkt() error! payload_len too long:%d.\n", __FILE__, __LINE__, payload_len + reserved_hdr_len); + return -1; + //assert(0); + } + + if((ADDR_TYPE_IPV4 == stream->addr.addrtype) + || (ADDR_TYPE_TCP == stream->addr.addrtype)){ + set_build_layer_tcp_args(thread_num, TH_PUSH|TH_ACK, MESA_rand_range(1000, 1460), 0); + } + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + + memcpy(send_handle->send_buf + reserved_hdr_len, payload, payload_len); + + send_len = build_net_layer_pkt(stream_pr, stream->addr.addrtype, payload_len, + send_handle->send_buf + reserved_hdr_len, snd_dir_reverse, raw_pkt); + if(send_len < 0){ + ret = -1; + goto err; + } + ret = packet_io_send(send_handle, reserved_hdr_len+payload_len, SEND_TYPE_LINK_INJECT, + low_net_layer_type, stream->routedir, thread_num, + feedback_buf, feedback_buf_len); + if(ret < 0){ + send_handle->tot_send_err++; + }else{ + send_handle->tot_send_pkt++; + send_handle->tot_send_byte += send_len; + } + + if(STREAM_TYPE_TCP == stream->type){ + g_SysInputInfo[thread_num][SEND_TCP_PKT]++; + g_SysInputInfo[thread_num][SEND_TCP_PKT_LEN]+=send_len; + }else{ + g_SysInputInfo[thread_num][SEND_UDP_PKT]++; + g_SysInputInfo[thread_num][SEND_UDP_PKT_LEN]+=send_len; + } + +err: + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_num); + +fun_exit: + if((ADDR_TYPE_IPV4 == stream->addr.addrtype) + || (ADDR_TYPE_TCP == stream->addr.addrtype)){ + detach_build_layer_tcp_args(thread_num); + } + + return ret; +} + +int MESA_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len, + const void *ext_raw_pkt, UCHAR snd_routedir) +{ + return __do_inject_pkt(stream, payload, payload_len, ext_raw_pkt, snd_routedir, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); +} + + +int MESA_inject_pkt_feedback(struct streaminfo *stream, const char *payload, int payload_len, + const void *ext_raw_pkt, UCHAR snd_routedir, + char *feedback_buf, int *feedback_buf_len) +{ + if((NULL == feedback_buf) || (NULL == feedback_buf_len)){ + return -2; + } + if(*feedback_buf_len <= 0){ + return -2; + } + + return __do_inject_pkt(stream, payload, payload_len, ext_raw_pkt, snd_routedir, + feedback_buf, feedback_buf_len); +} + +unsigned long packet_io_get_send_pkt_num(int thread_num) +{ + MESA_send_handle *send_handle = &g_send_handle[thread_num]; + + return send_handle->tot_send_pkt; +} + +unsigned long packet_io_get_send_pkt_err(int thread_num) +{ + MESA_send_handle *send_handle = &g_send_handle[thread_num]; + + return send_handle->tot_send_err; +} + +unsigned long packet_io_get_send_pkt_byte(int thread_num) +{ + MESA_send_handle *send_handle = &g_send_handle[thread_num]; + + return send_handle->tot_send_byte; +} + +int packet_io_set_max_rand_value(int rand_max) +{ + g_iMaxRandVal = rand_max; + return 0; +} + +int packet_io_set_rand_key(int rand_key) +{ + g_iRandKey = rand_key; + return 0; +} + +static int send_handle_init(int tot_thread_num) +{ + int i, ret; + int max_thread_num; +#if 0 /* 2018 lijia modify , ���Ӳ���������߳������������� */ + for(i = 0; i < tot_thread_num; i++){ +#else + max_thread_num = ((tot_thread_num) >= (INDEPENDENT_SEND_QUEUE_MAX_NUM)) ? (tot_thread_num) : (INDEPENDENT_SEND_QUEUE_MAX_NUM); + for(i = 0; i < max_thread_num; i++){ +#endif + g_send_handle[i].raw_ipv4_fd = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); + if(g_send_handle[i].raw_ipv4_fd < 0){ + printf("socket v4 error, %s\n", strerror(errno)); + return -1; + } + if(g_packet_io_ipv6_raw_socket){ + g_send_handle[i].raw_ipv6_fd = socket(PF_INET6, SOCK_RAW, IPPROTO_RAW); + if(g_send_handle[i].raw_ipv6_fd < 0){ + printf("socket v6 error, %s\n", strerror(errno)); + printf("Please disable IPv6 module, then try again!\n"); + return -1; + } + } + if(g_send_dev_name[0] != '\0'){ + ret = g_send_handle[i].raw_eth_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)); + if(g_send_handle[i].raw_eth_fd < 0){ + printf("socket raw eth error, %s\n", strerror(errno)); + return -1; + } + ret = snprintf(g_send_handle[i].saddr_raw_eth.sa_data, sizeof(g_send_handle[i].saddr_raw_eth.sa_data), + "%s", g_send_dev_name); + if(ret >= (int)sizeof(g_send_handle[i].saddr_raw_eth.sa_data)){ + printf("send device name is too long!\n"); + return -1; + } + g_send_handle[i].saddr_raw_eth.sa_family = PF_INET; + } + g_send_handle[i].threadnum = i; + +#if (0 == SAPP_AS_TARGET_SO) + g_send_handle[i].low_level_send_handle = dl_io_fun_list.dl_io_get_send_handle(i); + if(NULL == g_send_handle[i].low_level_send_handle){ + printf("dl_io_get_send_handle error !\n"); + return -1; + } +#endif + g_packet_dl_send_handle[i] = g_send_handle[i].low_level_send_handle; /* 20161117 lijia move from packet_io_init() */ + } + + return 0; +} + +/* 2015-01-04 lijia add, ��pappƽ̨Ǩ�Ƶ�sappƽ̨, �ײ㷢���ӿڲ�ͬ */ +int MESA_sendpacket_ethlayer(int thread_num,const char *data, int data_len, unsigned int target_id) +{ + int ret; + + if(data_len > MTU_MAX) + { + printf("data length is more than MTU, %d\n", data_len); + return -1; + } + +#if 0 /* for debug! */ + char send_buf[MTU_MAX]; + char debug_smac[6] = {0x74, 0x86, 0x7A, 0xD0, 0x12, 0xFC}; + char debug_dmac[6] = {0x00, 0x01, 0x6c, 0x53, 0xa9, 0x94}; + struct mesa_ethernet_hdr *eth_hdr = (struct mesa_ethernet_hdr *)data; + eth_hdr->ether_type = ntohs(ETHERTYPE_IP); + memcpy(eth_hdr->ether_shost, debug_smac, 6); + memcpy(eth_hdr->ether_dhost, debug_dmac, 6); +#endif + + ret = packet_io_send_raw(thread_num, (char *)data, data_len, target_id); + + return (ret); +} + +int sendpacket_init_new(int tot_thread_num) +{ + srand(time(NULL)); + + g_rand_seed = random(); + + if(send_handle_init(tot_thread_num) < 0){ + return -1; + } + + /* to do, TODO, + //get_gateway_info(); + + ����һ���߳�, ��̬��ȡĬ�����ص�MAC��ַ, ����Ŀ�������IPv4��ַ����������IP,����arp����, + pthread_create(sendpacket_keepalive_with_gateway); + */ + + return 0; +} + + +#define DIR_BIT_USE_MASK (0x81) +#define DIR_BIT_UNUSE_MASK (0x7E) + + +/*************************************************************************************** + NOTE: + MESA_sendpacket_xxx��MESA_fakepacket_send_xxxϵ�к�����, dir��sapp�е�routedir���岻ͬ, + pappƽ̨�е�dirʹ�����λbit��ʾ����, ������Ϊ0x00, ����Ϊ0x80, + ��sapp�е�routedir�����λ��ʾ����, ������Ϊ0x00, ����Ϊ0x01. + Ϊ��ͬʱ���ݴ�����ƽ̨�Ͳ��, ����MESA_dir_reverse()����, ���ڷ���. +****************************************************************************************/ +unsigned char MESA_dir_reverse(unsigned char raw_dir) +{ + raw_dir ^= DIR_BIT_USE_MASK; /* ͬʱ����sapp�;ɰ�WY���, ��ߺ����bitλͬʱ���� */ + + return raw_dir; +} + +static inline int dir_check(unsigned char raw_dir) +{ + if(raw_dir & DIR_BIT_UNUSE_MASK){ /* ����ֻʹ������ߺ����λbit, �����������ֵ,˵�������ת��dirʱ���˴��� */ + printf("dir = 0x%x, is invalid, only the most or least significant bit can be used!", raw_dir); + //assert(0); + return -1; + } + + return 0; +} + +static int __MESA_sendpacket_iplayer(int thread_index,const char *data, int data_len, u_int8_t dir, int layer_type) +{ + MESA_send_handle *send_handle; + int ret, offset = 0; + + send_handle = &g_send_handle[thread_index]; + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + switch(g_packet_io_cap_level){ + case CAP_LEVEL_IPV4: + offset = 0; + break; + case CAP_LEVEL_MAC: + offset = sizeof(struct mesa_ethernet_hdr); + break; + + default: + printf("MESA_sendpacket_iplayer: Invalid cap_mode:%d\n", g_packet_io_cap_level); + //exit(1); + return -1; + } + + if(data_len > (int)MTU_MAX-(int)sizeof(struct mesa_ethernet_hdr)){ + printf("TODO: MESA_sendpacket_iplayer error! datalen is more than MTU, need ip fragment!\n"); + return -1; + } + + memcpy(send_handle->send_buf + offset, data, data_len); + + ret = packet_io_send_fake_pkt(send_handle, data_len+sizeof(struct mesa_ethernet_hdr), SEND_TYPE_LINK_INJECT, + layer_type, dir, thread_index, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + g_SysInputInfo[thread_index][SEND_IP_RAW_PKT]++; + g_SysInputInfo[thread_index][SEND_IP_RAW_PKT_LEN]+=ret; + + return ret; +} + +int MESA_sendpacket_iplayer(int thread_index,const char *data, int data_len, u_int8_t dir) +{ + return __MESA_sendpacket_iplayer(thread_index, data, data_len, dir, __ADDR_TYPE_IP_PAIR_V4); +} + +int MESA_sendpacket_ipv6_layer(int thread_index,const char *data, int data_len, u_int8_t dir) +{ + return __MESA_sendpacket_iplayer(thread_index, data, data_len, dir, __ADDR_TYPE_IP_PAIR_V6); +} + +int MESA_fakepacket_send_ipv4(int thread_index,u_int8_t ttl, + u_int8_t protocol,u_int32_t sip, u_int32_t dip, const char *payload, + int payload_len,u_int8_t dir) +{ + MESA_send_handle *send_handle; + int ret, offset = 0; + u_int16_t ipid; + + send_handle = &g_send_handle[thread_index]; + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + switch(g_packet_io_cap_level){ + case CAP_LEVEL_IPV4: + offset = 0; + break; + case CAP_LEVEL_MAC: + offset = sizeof(struct mesa_ethernet_hdr); + break; + + default: + printf("MESA_fakepacket_send_ipv4: Invalid cap_mode:%d\n", g_packet_io_cap_level); + //exit(1); + return -1; + } + + if(payload_len > (int)MTU_MAX-(int)sizeof(struct mesa_ethernet_hdr)-(int)sizeof(struct mesa_ip4_hdr)){ + printf("TODO: MESA_fakepacket_send_ipv4 error! datalen is more than MTU, need ip fragment!\n"); + return -1; + } + + ipid = MESA_rand() % 65535; + sendpacket_build_ipv4(payload_len, 0, ipid, 0 , ttl, protocol, + htonl(sip), htonl(dip), payload, payload_len, send_handle->send_buf+offset); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), + SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + g_SysInputInfo[thread_index][SEND_IP_PKT]++; + g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=ret; + + return ret; +} + +int MESA_fakepacket_send_ipv4_detail(int thread_index,u_int8_t ttl, + u_int8_t protocol,u_int32_t sip, u_int32_t dip, u_int16_t ipid, + const char *payload, int payload_len,u_int8_t dir) +{ + MESA_send_handle *send_handle; + int ret, offset = 0; + + send_handle = &g_send_handle[thread_index]; + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + switch(g_packet_io_cap_level){ + case CAP_LEVEL_IPV4: + offset = 0; + break; + case CAP_LEVEL_MAC: + offset = sizeof(struct mesa_ethernet_hdr); + break; + + default: + printf("MESA_fakepacket_send_ipv4: Invalid cap_mode:%d\n", g_packet_io_cap_level); + //exit(1); + return -1; + } + + if(payload_len > (int)MTU_MAX-(int)sizeof(struct mesa_ethernet_hdr)-(int)sizeof(struct mesa_ip4_hdr)){ + printf("TODO: MESA_fakepacket_send_ipv4 error! datalen is more than MTU, need ip fragment!\n"); + return -1; + } + + sendpacket_build_ipv4(payload_len, 0, ipid, 0 , ttl, protocol, + htonl(sip), htonl(dip), payload, payload_len, send_handle->send_buf+offset); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), + SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + g_SysInputInfo[thread_index][SEND_IP_PKT]++; + g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=ret; + + return ret; +} + +int MESA_fakepacket_send_tcp(int thread_index,u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control,const char* payload,int payload_len, u_int8_t dir) +{ + MESA_send_handle *send_handle; + int ret, offset = 0; + u_int16_t tcp_win, ipid; + + send_handle = &g_send_handle[thread_index]; + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + switch(g_packet_io_cap_level){ + case CAP_LEVEL_IPV4: + offset = 0; + break; + case CAP_LEVEL_MAC: + offset = sizeof(struct mesa_ethernet_hdr); + break; + + default: + printf("MESA_fakepacket_send_tcp: Invalid cap_mode:%d\n", g_packet_io_cap_level); + //exit(1); + return -1; + } + + if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){ + printf("TODO: MESA_fakepacket_send_tcp error! datalen is more than MTU, need ip fragment!\n"); + return -1; + } + + tcp_win = MESA_rand_range(1460, 65500); + ipid = MESA_rand() % 65535; + + sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order, + control, tcp_win, 0, payload, payload_len, send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr)); + + sendpacket_build_ipv4(payload_len+SENDPACKET_TCP_H, 0, ipid, 0, 64, IPPROTO_TCP, + htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_tcp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), + SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + g_SysInputInfo[thread_index][SEND_TCP_PKT]++; + g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=ret; + + return ret; +} + + +int MESA_fakepacket_send_tcp_detail(int thread_index,u_int sip_host_order,u_int dip_host_order, + u_short ipid, u_char ip_ttl, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, u_short tcp_win, const char* payload,int payload_len, u_int8_t dir) +{ + MESA_send_handle *send_handle; + int ret, offset = 0; + + send_handle = &g_send_handle[thread_index]; + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + switch(g_packet_io_cap_level){ + case CAP_LEVEL_IPV4: + offset = 0; + break; + case CAP_LEVEL_MAC: + offset = sizeof(struct mesa_ethernet_hdr); + break; + + default: + printf("MESA_fakepacket_send_tcp: Invalid cap_mode:%d\n", g_packet_io_cap_level); + //exit(1); + return -1; + } + + if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){ + printf("TODO: MESA_fakepacket_send_tcp error! datalen is more than MTU, need ip fragment!\n"); + return -1; + } + + sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order, + control, tcp_win, 0, payload, payload_len, send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr)); + + sendpacket_build_ipv4(payload_len+SENDPACKET_TCP_H, 0, ipid, 0, ip_ttl, IPPROTO_TCP, + htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_tcp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), + SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + g_SysInputInfo[thread_index][SEND_TCP_PKT]++; + g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=ret; + + return ret; +} + +int MESA_fakepacket_send_udp(int thread_index, u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir) +{ + MESA_send_handle *send_handle; + int ret, offset = 0; + u_int16_t ipid; + + send_handle = &g_send_handle[thread_index]; + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + switch(g_packet_io_cap_level){ + case CAP_LEVEL_IPV4: + offset = 0; + break; + case CAP_LEVEL_MAC: + offset = sizeof(struct mesa_ethernet_hdr); + break; + + default: + printf("MESA_fakepacket_send_udp: Invalid cap_mode:%d\n", g_packet_io_cap_level); + //exit(1); + return -1; + } + + if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){ + printf("TODO: MESA_fakepacket_send_udp error! datalen is more than MTU, need ip fragment!\n"); + return -1; + } + + ipid = MESA_rand() % 65535; + + sendpacket_build_udp_dual_stack(sport_host_order, dport_host_order, payload, payload_len, payload_len, + send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr)); + + sendpacket_build_ipv4(payload_len+SENDPACKET_UDP_H, 0, ipid, 0, 64, IPPROTO_UDP, + htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_udp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), + SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + g_SysInputInfo[thread_index][SEND_UDP_PKT]++; + g_SysInputInfo[thread_index][SEND_UDP_PKT_LEN]+=ret; + + return ret; +} + +int MESA_fakepacket_send_udp_detail(int thread_index, u_int sip_host_order, u_int dip_host_order, + u_short ipid, u_int8_t ip_ttl, u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir) +{ + MESA_send_handle *send_handle; + int ret, offset = 0; + + send_handle = &g_send_handle[thread_index]; + + send_handle->send_buf = packet_io_get_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + switch(g_packet_io_cap_level){ + case CAP_LEVEL_IPV4: + offset = 0; + break; + case CAP_LEVEL_MAC: + offset = sizeof(struct mesa_ethernet_hdr); + break; + + default: + printf("MESA_fakepacket_send_udp: Invalid cap_mode:%d\n", g_packet_io_cap_level); + //exit(1); + return -1; + } + + if(payload_len > (int)MTU_MAX- (int)sizeof(struct mesa_ethernet_hdr)- (int)sizeof(struct mesa_ip4_hdr)- (int)sizeof(struct mesa_tcp_hdr)){ + printf("TODO: MESA_fakepacket_send_udp error! datalen is more than MTU, need ip fragment!\n"); + return -1; + } + + sendpacket_build_udp_dual_stack(sport_host_order, dport_host_order, payload, payload_len, payload_len, + send_handle->send_buf+offset+sizeof(struct mesa_ip4_hdr)); + + sendpacket_build_ipv4(payload_len+SENDPACKET_UDP_H, 0, ipid, 0, ip_ttl, IPPROTO_UDP, + htonl(sip_host_order), htonl(dip_host_order), NULL, 0, send_handle->send_buf+offset); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len); + + sendpacket_do_checksum(send_handle->send_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + ret = packet_io_send_fake_pkt(send_handle, payload_len+sizeof(struct mesa_udp_hdr)+sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), + SEND_TYPE_LINK_INJECT, __ADDR_TYPE_IP_PAIR_V4, dir, thread_index, + (char *)KILL_TCP_PHONY_POINTER, (int *)KILL_TCP_PHONY_POINTER); + + packet_io_free_sendbuf(SEND_TYPE_LINK_INJECT, thread_index); + + g_SysInputInfo[thread_index][SEND_UDP_PKT]++; + g_SysInputInfo[thread_index][SEND_UDP_PKT_LEN]+=ret; + + return ret; +} + +#if IOMODE_MARSIO +#include "marsio.h" +#include "mrtunnat.h" +#include <dlfcn.h> +static struct mr_instance *dl_io_marsio4_instance = NULL; +extern struct dl_io_lib_name g_dl_io_lib_info[]; +extern int g_packet_io_cap_mode; +extern int marsio_send_burst_with_options_for_tcpdumpmesa(struct mr_sendpath * sendpath, queue_id_t sid, marsio_buff_t * mbufs[], int nr_mbufs, uint16_t options); +static struct mr_instance *sapp_get_marsio_instance(void) +{ + void *dl_handle; + char lib_path[256]; + void *address_of_sapp_marsio4_instance; + + snprintf(lib_path, 256, "%s/%s", "platform_lib", g_dl_io_lib_info[g_packet_io_cap_mode].lib_name); + + dl_handle = dlopen(lib_path, RTLD_NOW); + if(NULL == dl_handle){ + printf("\033[41m[Error]dlopen %s error!\033[0m\n", lib_path); + return NULL; + } + + address_of_sapp_marsio4_instance = dlsym(dl_handle, "sapp_marsio4_instance"); + if(NULL == address_of_sapp_marsio4_instance){ + printf("\033[41m[Error]dlsym %s from %s error!\033[0m\n", "sapp_marsio4_instance", lib_path); + return NULL; + } + + /* dlsym ��ȡ����sapp_marsio4_instance���ŵ���ʼ��ַ, �Դ˵�ַȡ8bytesֵ, ����ָ�����ʵֵ */ + memcpy(&dl_io_marsio4_instance, address_of_sapp_marsio4_instance, sizeof(void *)); + return dl_io_marsio4_instance; +} + + +static void sapp_fakepacket_set_vxlan_options(struct mr_tunnat_ctrlzone *mr_ctrlzone, SAPP_TLV_T *option) +{ + switch(option->type){ + case SAPP_SEND_OPT_GDEV_DMAC: + memcpy(mr_ctrlzone->g_device_mac, option->array_value, 6); + break; + + case SAPP_SEND_OPT_GDEV_SMAC: + memcpy(mr_ctrlzone->l_device_mac, option->array_value, 6); + break; + + case SAPP_SEND_OPT_GDEV_DIP: + mr_ctrlzone->g_device_in_addr = option->int_value; + break; + + case SAPP_SEND_OPT_GDEV_SIP: + mr_ctrlzone->l_device_in_addr = option->int_value; + break; + + case SAPP_SEND_OPT_GDEV_UDP_DPORT: + /* default 4789, do nothing */ + break; + + case SAPP_SEND_OPT_GDEV_UDP_SPORT: + mr_ctrlzone->l4_src_port = option->short_value; + break; + + case SAPP_SEND_OPT_VXLAN_VPN_ID: + mr_ctrlzone->g_device_vpn_id = option->int_value; + mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_NO_SESSION; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */ + break; + + case SAPP_SEND_OPT_VXLAN_LINK_ID: + mr_ctrlzone->g_device_linkpair = option->int_value; + mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_NO_SESSION; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */ + break; + + case SAPP_SEND_OPT_VXLAN_LINK_ENCAP_TYPE: + mr_ctrlzone->g_device_outer_encap_type = option->char_value; + break; + + case SAPP_SEND_OPT_VXLAN_LINK_DIR: + mr_ctrlzone->route_dir = option->char_value; + mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_NO_SESSION; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */ + break; + + case SAPP_SEND_OPT_INNER_LINK_ENCAP_TYPE: + mr_ctrlzone->g_device_inner_encap_type = option->char_value; + break; + + case SAPP_SEND_OPT_VIRTUAL_LINK_ID: + mr_ctrlzone->virtual_link_id = option->long_value; + mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_VIRTUAL_LINK_ID; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */ + break; + + case SAPP_SEND_OPT_REHASH_INDEX: + mr_ctrlzone->rehash_index = option->long_value; + mr_ctrlzone->action |= TUNNAT_CZ_ACTION_ENCAP_VIRTUAL_LINK_ID; /* ֱ�ӹ�����������ٷ���, ����Ҫ������� */ + break; + + case SAPP_SEND_OPT_VXLAN_FLAGS: + //todo, dpdk driver not support, fix value 0x08 + break; + + default: + sapp_runtime_log(20, "sendpacket set vxlan options error, invalid opt type:%d\n", option->type); + break; + } + + return; +} + +/* + �˺�����ipv4, ipv6������������, ��ether_type_host��������. + data: ����ipͷ��������ip��; + data_len: ����ipͷ������. +*/ +static int __MESA_sendpacket_iplayer_options(int thread_index,const char *data, int data_len, + u_int8_t dir, SAPP_TLV_T *options, int opt_num, unsigned short ether_type_host) +{ + /* marsioϵ�к���0��ʾ����, -1��ʾ����, g_serialϵ�к������������ֽ���, ����-1 */ + int inner_ret; + marsio_buff_t *send_mbuf[1]; + unsigned char *real_buf; + struct mr_tunnat_ctrlzone mr_ctrlzone; + int i; + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index); + if(inner_ret < 0){ + return -1; + } + g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++; + + real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], data_len+sizeof(struct mesa_ethernet_hdr)); + struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf; + inner_ehdr->ether_type = ntohs(ether_type_host);/* �ײ���Ϊethernet */ + + /* �˴�ֻ������IP����ص�ѡ��, vxlan���ѡ���ڹ�������sapp_fakepacket_set_vxlan_options()���� */ + memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone)); + for(i = 0; i < opt_num; i++){ + if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){ + memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN); + }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){ + memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN); + }else{ + sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]); + } + } + memcpy(real_buf + sizeof(struct mesa_ethernet_hdr), data, data_len); + + mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER; + mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */ + marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); + inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index, + send_mbuf, 1, MARSIO_SEND_OPT_FAST); + if(inner_ret < 0){ + return -1; + } + + g_SysInputInfo[thread_index][SEND_IP_PKT]++; + g_SysInputInfo[thread_index][SEND_IP_PKT_LEN] += data_len; + + g_SysInputInfo[thread_index][PKT_MARSIO_SND]++; + + return data_len; +} + + +int MESA_sendpacket_iplayer_options(int thread_index,const char *data, int data_len, + u_int8_t dir, SAPP_TLV_T *options, int opt_num) +{ + return __MESA_sendpacket_iplayer_options(thread_index, data, data_len, dir, options, opt_num, ETHERTYPE_IP); +} + +int MESA_sendpacket_ipv6_layer_options(int thread_index,const char *data, int data_len, + u_int8_t dir, SAPP_TLV_T *options, int opt_num) +{ + return __MESA_sendpacket_iplayer_options(thread_index, data, data_len, dir, options, opt_num, ETHERTYPE_IPv6); +} + +int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol, + uint32_t sip_host_order, uint32_t dip_host_order, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num) +{ + int snd_len, inner_ret; + marsio_buff_t *send_mbuf[1]; + u_int16_t ipid = MESA_rand() & 0xFFFF; + u_int8_t ip_ttl = MESA_rand() % 64 + 32; + int thread_index = stream->threadnum; + int i; + + struct mr_tunnat_ctrlzone mr_ctrlzone; + unsigned char *real_buf; + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index); + if(inner_ret < 0){ + return -1; + } + g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++; + + /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */ + real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr)); + struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf; + inner_ehdr->ether_type = ntohs(ETHERTYPE_IP);/* �ײ���Ϊethernte */ + + /* �˴�ֻ������IP����ص�ѡ��, vxlan���ѡ���ڹ�������sapp_fakepacket_set_vxlan_options()���� */ + memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone)); + for(i = 0; i < opt_num; i++){ + if(SAPP_SEND_OPT_IP_ID == options[i].type){ + ipid = options[i].short_value; + }else if(SAPP_SEND_OPT_IP_TTL == options[i].type){ + ip_ttl = options[i].char_value; + }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){ + memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN); + }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){ + memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN); + }else{ + sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]); + } + } + sendpacket_build_ipv4(payload_len, 0, ipid, 0 , ip_ttl, protocol, + htonl(sip_host_order), htonl(dip_host_order), payload, payload_len, + (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr)); + + sendpacket_do_checksum(real_buf + sizeof(struct mesa_ethernet_hdr), IPPROTO_IP, SENDPACKET_IP_H); + + if(payload){ + memcpy(real_buf + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr), payload, payload_len); + } + + mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER; + mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */ + marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); + inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index, + send_mbuf, 1, MARSIO_SEND_OPT_FAST); + + if(inner_ret < 0){ + return -1; + } + + snd_len = sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr) + payload_len; + g_SysInputInfo[thread_index][SEND_IP_PKT]++; + g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=snd_len; + + g_SysInputInfo[thread_index][PKT_MARSIO_SND]++; + + return snd_len; +} + +int MESA_fakepacket_send_ipv6_options(const struct streaminfo *stream, uint8_t protocol, + struct in6_addr *sip, struct in6_addr *dip, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num) +{ + int inner_ret, snd_len; + u_int8_t ip_ttl = MESA_rand() % 64 + 32; + int thread_index = stream->threadnum; + int i; + marsio_buff_t *send_mbuf[1]; + struct mr_tunnat_ctrlzone mr_ctrlzone; + unsigned char *real_buf; + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index); + if(inner_ret < 0){ + return -1; + } + g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++; + + /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */ + real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr)); + struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf; + inner_ehdr->ether_type = ntohs(ETHERTYPE_IPv6);/* �ײ���Ϊethernet */ + + /* �˴�ֻ������IP����ص�ѡ��, vxlan���ѡ���ڹ�������sapp_fakepacket_set_vxlan_options()���� */ + memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone)); + for(i = 0; i < opt_num; i++){ + if(SAPP_SEND_OPT_IP_TTL == options[i].type){ + ip_ttl = options[i].char_value; + }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){ + memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN); + }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){ + memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN); + }else{ + sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]); + } + } + sendpacket_build_ipv6(0, 0, payload_len, protocol, ip_ttl, sip, dip, + payload, payload_len, + (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr)); + + mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER; + mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */ + marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); + inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index, + send_mbuf, 1, MARSIO_SEND_OPT_FAST); + if(inner_ret < 0){ + return -1; + } + + snd_len = sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr) + payload_len; + g_SysInputInfo[thread_index][SEND_IP_PKT]++; + g_SysInputInfo[thread_index][SEND_IP_PKT_LEN]+=snd_len; + + g_SysInputInfo[thread_index][PKT_MARSIO_SND]++; + + return snd_len; +} + +int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream, + u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num) +{ + int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr); + int thread_index = stream->threadnum; + marsio_buff_t *send_mbuf[1]; + struct mr_tunnat_ctrlzone mr_ctrlzone; + unsigned char *real_buf; + unsigned short ipid = MESA_rand() & 0xFFFF; + unsigned short tcp_win = MESA_rand_range(8192, 32768); + unsigned char ip_ttl = MESA_rand_range(32,65); + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index); + if(inner_ret < 0){ + return -1; + } + g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++; + + /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */ + real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr)); + struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf; + inner_ehdr->ether_type = ntohs(ETHERTYPE_IP);/* �ײ���Ϊethernte */ + + memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone)); + for(i = 0; i < opt_num; i++){ + if(SAPP_SEND_OPT_IP_ID == options[i].type){ + ipid = options[i].short_value; + }else if(SAPP_SEND_OPT_IP_TTL == options[i].type){ + ip_ttl = options[i].char_value; + }if(SAPP_SEND_OPT_TCP_WIN == options[i].type){ + tcp_win = options[i].short_value; + }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){ + memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN); + }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){ + memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN); + }else{ + sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]); + } + } + + sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order, + control, tcp_win, 0, payload, payload_len, real_buf+offset+sizeof(struct mesa_ip4_hdr)); + + sendpacket_build_ipv4(payload_len+SENDPACKET_TCP_H, 0, ipid, 0, ip_ttl, IPPROTO_TCP, + htonl(sip_host_order), htonl(dip_host_order), NULL, 0, real_buf+offset); + + sendpacket_do_checksum(real_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); + + sendpacket_do_checksum(real_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER; + mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */ + marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); + inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index, + send_mbuf, 1, MARSIO_SEND_OPT_FAST); + + if(inner_ret < 0){ + return -1; + } + + snd_len = sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_tcp_hdr) + payload_len; + + g_SysInputInfo[thread_index][SEND_TCP_PKT]++; + g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len; + + g_SysInputInfo[thread_index][PKT_MARSIO_SND]++; + + return snd_len; +} + + +int MESA_fakepacket_send_ipv6_tcp_options(const struct streaminfo *stream, + struct in6_addr *sip, struct in6_addr *dip, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num) +{ + int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr); + int thread_index = stream->threadnum; + marsio_buff_t *send_mbuf[1]; + struct mr_tunnat_ctrlzone mr_ctrlzone; + unsigned char *real_buf; + unsigned short tcp_win = MESA_rand_range(8192, 32768); + unsigned char ip_ttl = MESA_rand_range(32,65); + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index); + if(inner_ret < 0){ + return -1; + } + g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++; + + /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */ + real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_tcp_hdr) + sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr)); + struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf; + inner_ehdr->ether_type = ntohs(ETHERTYPE_IPv6);/* �ײ���Ϊethernte */ + + memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone)); + for(i = 0; i < opt_num; i++){ + if(SAPP_SEND_OPT_IP_TTL == options[i].type){ + ip_ttl = options[i].char_value; + }if(SAPP_SEND_OPT_TCP_WIN == options[i].type){ + tcp_win = options[i].short_value; + }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){ + memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN); + }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){ + memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN); + }else{ + sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]); + } + } + + sendpacket_build_tcp(sport_host_order, dport_host_order, sseq_host_order, sack_host_order, + control, tcp_win, 0, payload, payload_len, real_buf+offset+sizeof(struct mesa_ip6_hdr)); + + sendpacket_build_ipv6(0, 0, payload_len + sizeof(struct mesa_tcp_hdr), IPPROTO_TCP, ip_ttl, sip, dip, + NULL, 0, + (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr)); + + sendpacket_do_checksum(real_buf+offset, IPPROTO_TCP, SENDPACKET_TCP_H+payload_len); + + mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER; + mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */ + marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); + inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index, + send_mbuf, 1, MARSIO_SEND_OPT_FAST); + if(inner_ret < 0){ + return -1; + } + + snd_len = sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_tcp_hdr) + payload_len; + g_SysInputInfo[thread_index][SEND_TCP_PKT]++; + g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len; + + g_SysInputInfo[thread_index][PKT_MARSIO_SND]++; + + return snd_len; +} + +int MESA_fakepacket_send_udp_options(const struct streaminfo *stream, + u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num) +{ + int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr); + int thread_index = stream->threadnum; + marsio_buff_t *send_mbuf[1]; + struct mr_tunnat_ctrlzone mr_ctrlzone; + unsigned char *real_buf; + unsigned short ipid = MESA_rand(); + unsigned char ip_ttl = MESA_rand_range(32, 64); + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index); + if(inner_ret < 0){ + return -1; + } + g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++; + + /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */ + real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr)); + struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf; + inner_ehdr->ether_type = ntohs(ETHERTYPE_IP);/* �ײ���Ϊethernte */ + + memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone)); + for(i = 0; i < opt_num; i++){ + if(SAPP_SEND_OPT_IP_ID == options[i].type){ + ipid = options[i].short_value; + }else if(SAPP_SEND_OPT_IP_TTL == options[i].type){ + ip_ttl = options[i].char_value; + }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){ + memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN); + }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){ + memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN); + }else{ + sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]); + } + } + + sendpacket_build_udp(sport_host_order, dport_host_order, payload, payload_len, + real_buf+offset+sizeof(struct mesa_ip4_hdr)); + + sendpacket_build_ipv4(payload_len+SENDPACKET_UDP_H, 0, ipid, 0, ip_ttl, IPPROTO_UDP, + htonl(sip_host_order), htonl(dip_host_order), NULL, 0, real_buf+offset); + + sendpacket_do_checksum(real_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len); + + sendpacket_do_checksum(real_buf+offset, IPPROTO_IP, SENDPACKET_IP_H); + + if((mr_ctrlzone.action & TUNNAT_CZ_ACTION_ENCAP_NO_SESSION) == 0){ + mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER; + } + mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */ + marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); + inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index, + send_mbuf, 1, MARSIO_SEND_OPT_FAST); + + if(inner_ret < 0){ + return -1; + } + + snd_len = sizeof(struct mesa_ip4_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_udp_hdr) + payload_len; + g_SysInputInfo[thread_index][SEND_TCP_PKT]++; + g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len; + + g_SysInputInfo[thread_index][PKT_MARSIO_SND]++; + + return snd_len; +} + +int MESA_fakepacket_send_ipv6_udp_options(const struct streaminfo *stream, + struct in6_addr *sip, struct in6_addr *dip, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num) +{ + int i, snd_len, inner_ret, offset = sizeof(struct mesa_ethernet_hdr); + int thread_index = stream->threadnum; + marsio_buff_t *send_mbuf[1]; + struct mr_tunnat_ctrlzone mr_ctrlzone; + unsigned char *real_buf; + unsigned char ip_ttl = MESA_rand_range(32, 64); + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + inner_ret = marsio_buff_malloc_global(dl_io_marsio4_instance, send_mbuf, 1, MARSIO_SOCKET_ID_ANY, thread_index); + if(inner_ret < 0){ + return -1; + } + g_SysInputInfo[thread_index][PKT_MARSIO_MALLOC]++; + + /* �˴�ʹ��append������mtod, append�ڲ�ʵ�ʰ�����set datalen�IJ��� */ + real_buf = (unsigned char *)marsio_buff_append(send_mbuf[0], payload_len + sizeof(struct mesa_udp_hdr) + sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr)); + struct mesa_ethernet_hdr *inner_ehdr = (struct mesa_ethernet_hdr *)real_buf; + inner_ehdr->ether_type = ntohs(ETHERTYPE_IPv6);/* �ײ���Ϊethernte */ + + memset(&mr_ctrlzone, 0 , sizeof(struct mr_tunnat_ctrlzone)); + for(i = 0; i < opt_num; i++){ + if(SAPP_SEND_OPT_IP_TTL == options[i].type){ + ip_ttl = options[i].char_value; + }else if(SAPP_SEND_OPT_INNER_SMAC == options[i].type){ + memcpy(inner_ehdr->ether_shost, options[i].array_value, ETHER_ADDR_LEN); + }else if(SAPP_SEND_OPT_INNER_DMAC == options[i].type){ + memcpy(inner_ehdr->ether_dhost, options[i].array_value, ETHER_ADDR_LEN); + }else{ + sapp_fakepacket_set_vxlan_options(&mr_ctrlzone, &options[i]); + } + } + + sendpacket_build_udp(sport_host_order, dport_host_order, payload, payload_len, + real_buf+offset+sizeof(struct mesa_ip6_hdr)); + + sendpacket_build_ipv6(0, 0, payload_len + sizeof(struct mesa_udp_hdr), IPPROTO_UDP, ip_ttl, sip, dip, + NULL, 0, + (unsigned char *)real_buf + sizeof(struct mesa_ethernet_hdr)); + + sendpacket_do_checksum(real_buf+offset, IPPROTO_UDP, SENDPACKET_UDP_H+payload_len); + + mr_ctrlzone.action |= TUNNAT_CZ_ACTION_ENCAP_INNER | TUNNAT_CZ_ACTION_ENCAP_OUTER; + mr_ctrlzone.route_dir = dir; /* ͨ��ѡ��Ҳ������, �����DZ����˽ӿ�ֱ������dir�IJ���, �ӿ�dir���� */ + marsio_buff_ctrlzone_set(send_mbuf[0], 0, &mr_ctrlzone, sizeof(struct mr_tunnat_ctrlzone)); + inner_ret = marsio_send_burst_with_options_for_tcpdumpmesa((struct mr_sendpath *)g_packet_device_alias[0].dl_io_param, thread_index, + send_mbuf, 1, MARSIO_SEND_OPT_FAST); + if(inner_ret < 0){ + return -1; + } + + snd_len = sizeof(struct mesa_ip6_hdr)+sizeof(struct mesa_ethernet_hdr) +sizeof(struct mesa_udp_hdr) + payload_len; + g_SysInputInfo[thread_index][SEND_TCP_PKT]++; + g_SysInputInfo[thread_index][SEND_TCP_PKT_LEN]+=snd_len; + + g_SysInputInfo[thread_index][PKT_MARSIO_SND]++; + + return snd_len; +} +#endif + +int sapp_forward_current_pkt(const struct streaminfo *stream, unsigned int target_id) +{ + int ret; +#if IOMODE_MARSIO + marsio_buff_t *raw_mbuf, *new_clone_buf; + const struct streaminfo_private *stream_pr = (const struct streaminfo_private *)stream; + + if(NULL == dl_io_marsio4_instance){ + dl_io_marsio4_instance = sapp_get_marsio_instance(); + } + + if(NULL == stream_pr->raw_pkt){ /* ����������ʱ��̭����, ����Ե��ô˽ӿ� */ + return 0; + } + + /* TODO: + �жϵ�ǰ���Ƿ��������, ���ӷ������ص�TCPALL��, + �������io_lib_pkt_referenceָ��dpdk���ڴ�, ��û�и��Ʊ���, + ����ʱ�ᵼ���ڴ����. + + NOTE: + ��ʵ���������ޱ�Ҫ, ת����������ص�TCPALL��, ��deal_unorder���������������TCPALL�ӿ�! + */ + if((stream->addr.pkttype & PKT_TYPE_TCPREORDER) != 0){ + return 0; + } + raw_mbuf = (marsio_buff_t *)stream_pr->raw_pkt->io_lib_pkt_reference; + + assert(raw_mbuf); + + /* NOTE, + marsio��ͬʱ���հ����������Ӧ����������ʱ��������, + ���Դ˴�����Ӧ����������֮ǰ, ��cloneһ��new_clone_buf, ���ͺ���Զ�free. + ��עԭʼ���Ļ���ԭ����raw_mbuf. + */ + new_clone_buf = marsio_buff_clone_with_options(dl_io_marsio4_instance, raw_mbuf, + MARSIO_SOCKET_ID_ANY, stream->threadnum, + MR_BUFF_CLONE_BUFF | MR_BUFF_CLONE_CTRLZONE); + + assert(new_clone_buf); + g_SysInputInfo[stream->threadnum][PKT_MARSIO_MALLOC]++; + + ret = marsio_send_burst((struct mr_sendpath *)g_packet_device_alias[target_id].dl_io_param, + stream->threadnum, &new_clone_buf, 1); + g_SysInputInfo[stream->threadnum][PKT_MARSIO_SND]++; + +#else + printf("sapp_forward_current_pkt() not support in non-marsio mode, TODO!\n"); + return -1;/* ����ģʽtodo */ +#endif + + return ret; +} + + +#ifdef __cplusplus +} +#endif + @@ -1 +1,2 @@ -make clean; make +rm -rf ./build +make -f cmake-makefile debug |
