diff --git a/inc/tsg_rule.h b/inc/tsg_rule.h index 17cb903..36a76a8 100644 --- a/inc/tsg_rule.h +++ b/inc/tsg_rule.h @@ -26,6 +26,7 @@ enum TSG_METHOD_TYPE TSG_METHOD_TYPE_ALERT, TSG_METHOD_TYPE_RATE_LIMIT, TSG_METHOD_TYPE_MIRRORED, + TSG_METHOD_TYPE_TAMPER, TSG_METHOD_TYPE_MAX }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d26731d..4d08912 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,8 @@ cmake_minimum_required(VERSION 2.8) add_definitions(-fPIC) -set(SRC tsg_entry.cpp tsg_rule.cpp tsg_ssl_utils.cpp tsg_send_log.cpp tsg_statistic.cpp tsg_ssh_utils.cpp tsg_gtp_signaling.cpp tsg_traffic_mirror.cpp tsg_send_raw_packet.cpp tsg_action.cpp tsg_leaky_bucket.cpp tsg_dns.cpp) +set(SRC tsg_entry.cpp tsg_rule.cpp tsg_ssl_utils.cpp tsg_send_log.cpp tsg_statistic.cpp tsg_ssh_utils.cpp tsg_gtp_signaling.cpp tsg_traffic_mirror.cpp tsg_send_raw_packet.cpp tsg_action.cpp + tsg_leaky_bucket.cpp tsg_dns.cpp tsg_icmp.cpp tsg_tamper.cpp) include_directories(${CMAKE_SOURCE_DIR}/inc) include_directories(/opt/MESA/include/MESA/) diff --git a/src/tsg_action.cpp b/src/tsg_action.cpp index 7eace33..53fcfd4 100644 --- a/src/tsg_action.cpp +++ b/src/tsg_action.cpp @@ -549,10 +549,17 @@ static unsigned char do_action_reset(const struct streaminfo *a_stream, Maat_rul return STATE_DROPPKT|STATE_DROPME; } -static unsigned char do_action_drop(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol) + +static unsigned char do_action_drop(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *a_packet) { + if(user_region-> drop_para != NULL){ + if(user_region->drop_para->send_icmp_unreachable_enable){ + send_icmp_unreachable(a_stream, a_packet); + } + } + switch(protocol) - { + { case PROTO_DNS: return STATE_GIVEME|STATE_DROPPKT; default: @@ -642,7 +649,7 @@ static unsigned char do_action_block_xxx(const struct streaminfo *a_stream, Maat { if(user_region==NULL || user_region->deny==NULL) { - return do_action_drop(a_stream, p_result, protocol); + return do_action_drop(a_stream, p_result, user_region, protocol, a_packet); } switch(protocol) @@ -694,8 +701,8 @@ static unsigned char do_action_redirect_xxx(const struct streaminfo *a_stream, M { if(user_region==NULL || user_region->deny==NULL) { - return do_action_drop(a_stream, p_result, protocol); - } + return do_action_drop(a_stream, p_result, user_region, protocol, user_data); + } switch(protocol) { @@ -713,6 +720,16 @@ static unsigned char do_action_redirect_xxx(const struct streaminfo *a_stream, M return STATE_DROPME|STATE_DROPPKT; } +static unsigned char do_action_tamper(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, tsg_protocol_t protocol, const void *user_data) +{ + if(user_region==NULL) + { + return do_action_drop(a_stream, p_result, user_region, protocol, user_data); + } + + return send_tamper_xxx(a_stream, user_data); +} + unsigned char tsg_deal_deny_action(const struct streaminfo *a_stream, Maat_rule_t *p_result, tsg_protocol_t protocol, enum ACTION_RETURN_TYPE type, const void *user_data) { unsigned char local_state=STATE_GIVEME; @@ -734,7 +751,7 @@ unsigned char tsg_deal_deny_action(const struct streaminfo *a_stream, Maat_rule_ switch(method_type) { case TSG_METHOD_TYPE_DROP: - local_state=do_action_drop(a_stream, p_result, protocol); + local_state=do_action_drop(a_stream, p_result, user_region, protocol, user_data); if(protocol==PROTO_DNS && type==ACTION_RETURN_TYPE_APP) { local_state=set_drop_stream(a_stream, protocol); @@ -753,6 +770,9 @@ unsigned char tsg_deal_deny_action(const struct streaminfo *a_stream, Maat_rule_ case TSG_METHOD_TYPE_RATE_LIMIT: local_state=do_action_ratelimit(a_stream, p_result, user_region, type); break; + case TSG_METHOD_TYPE_TAMPER: + local_state=do_action_tamper(a_stream, p_result, user_region, protocol, user_data); + break; default: break; } diff --git a/src/tsg_entry.cpp b/src/tsg_entry.cpp index 23e2645..cd3a2d0 100644 --- a/src/tsg_entry.cpp +++ b/src/tsg_entry.cpp @@ -1641,26 +1641,29 @@ static unsigned char tsg_master_data_entry(const struct streaminfo *a_stream, vo int ssh_project_id = project_customer_register("SKETCH_PROTO_CTX_LABEL", PROJECT_VAL_TYPE_STRUCT); if (ssh_project_id >= 0) { - session_record_ctx * ssh_session_record_ctx = (session_record_ctx *)project_req_get_struct(a_stream, ssh_project_id); - if (ssh_session_record_ctx != NULL && ssh_session_record_ctx->proto_type == PROTO_SSH) - { - tsg_log_t log_msg; - log_msg.a_stream = (streaminfo *)a_stream; - log_msg.result = p_result; - log_msg.result_num = 1; + session_record_ctx *ssh_session_record_ctx = (session_record_ctx *)project_req_get_struct(a_stream, ssh_project_id); + if (ssh_session_record_ctx != NULL && ssh_session_record_ctx->proto_type == PROTO_SSH) + { + tsg_log_t log_msg; + log_msg.a_stream = (streaminfo *)a_stream; + log_msg.result = context->result; + log_msg.result_num = context->hit_cnt; - struct TLD_handle_t *_handle = TLD_duplicate(ssh_session_record_ctx->log); - if (_handle != NULL) - { - tsg_send_log(g_tsg_log_instance, _handle, &log_msg, thread_seq); - } - } + struct TLD_handle_t *_handle = TLD_duplicate(ssh_session_record_ctx->log); + if (_handle != NULL) + { + tsg_send_log(g_tsg_log_instance, _handle, &log_msg, thread_seq); + } + } } } - context->is_log=1; - master_send_log(a_stream, context->result, context->hit_cnt, context, thread_seq); + if (context->proto != PROTO_SSH) + { + context->is_log = 1; + master_send_log(a_stream, context->result, context->hit_cnt, context, thread_seq); + } } - *pme=NULL; + *pme = NULL; } return state; diff --git a/src/tsg_icmp.cpp b/src/tsg_icmp.cpp new file mode 100644 index 0000000..7d977ec --- /dev/null +++ b/src/tsg_icmp.cpp @@ -0,0 +1,212 @@ +#include +#include +#include +#include + +#include "tsg_entry.h" +#include "tsg_protocol_common.h" + +#define IPV4_TYPE 1 //ADDR_TYPE_IPV4 ==1 , 取的enum 0x0800 +#define IPV6_TYPE 2 //ADDR_TYPE_IPV6 ==2 0x86dd +#define TCP_TYPE 0x06 +#define UDP_TYPE 0x11 +#define ICMP_PROTOCOL_TYPE 0x01 //ipv4 icmp proctocol +#define ICMPV6_PROTOCAL_TYPE 0x3a //ipv6 icmpv6 protocl + +#define ICMPV4_UNREACHABLE 0x03 +#define ICMPV4_PORT_UNREACHABLE 0x03 +#define ICMPV6_UNREACHABLE 0x01 +#define ICMPV6_PORT_UNREACHABLE 0X04 + +#define MAC_LEN 6 +#define MAC_LEN_2 ((MAC_LEN)+(MAC_LEN)) +#define ETH_IP_TYPE_LEN 2 +#define ETH_LEN ((MAC_LEN_2)+(ETH_IP_TYPE_LEN)) + +#define IPV4_LEN 20 +#define IPV4_IP_LEN 4 +#define IPV4_IP_LEN_INDEX 2 //eth_len(14)+ ip_len_index(2) +#define IPV6_LEN 40 +#define IPV6_IP_LEN 16 +#define IPV6_IP_PAYLOAD_INDEX 4 // ipv6_payload_index(4) +#define ICMP_IPV4_PROTOCOL_TYPE_LEN 24 +#define ICMP_HEAD_LEN 8 +#define ICMPV4_SOURCE_MAX_LEN 64 +#define ICMPV4_MAX_LEN ((ICMPV4_SOURCE_MAX_LEN)+(ICMP_HEAD_LEN)) +#define IPV6_PESUDO_HEAD_LEN 40 + +//icmpv6的srcPacket len需要再确认 +#define ICMP_MAX_LEN 190 //eth_len(14) + ipv6_len(40) + ICMP_MAX_LEN(8+128) +#define ICMP_SRCPACKET_MAX_LEN 64 +#define ICMPV6_SRCPACKET_MAX_LEN 128 + +typedef struct icmpv4{ + char type; + char code; + short checksum; + char un_user[4]; + char srcPacket[ICMPV6_SRCPACKET_MAX_LEN]; +}icmpv4_st, icmpv6_st; + +short in_checksum(void *pkg, int size) +{ + int nleft = size; + int sum = 0; + unsigned short *w = (unsigned short *)pkg; + unsigned short answer = 0; + + while (nleft > 1) + { + sum += *w++; + nleft -= 2; + } + + if (nleft == 1) + { + * (unsigned char *) (&answer) = *(unsigned char *)w; + sum += answer; + } + + while (sum >> 16){ + sum = (sum & 0xFFFF) + (sum >> 16); + } + answer = ~sum &0xffff; + + return answer; +} + +static void format_icmpv4(const char *raw_pkt, char *buf, int *len){ + char ipv4[IPV4_LEN] = {0}; + icmpv4_st icmpst = {0}; + short src_ipv4_total_len = 0; + short icmpv4_complete_len = 0; + short icmp_len = 0; + short icmp_srcpacket_len = 0; + short icmp_start_len = IPV4_LEN; + short ipv4_total_len = 0; + short ipv4_checksum = 0; + short sip_len = 12; //skip sip start index + short dip_len = 16; //skip dip start index + + memcpy(&src_ipv4_total_len, &raw_pkt[IPV4_IP_LEN_INDEX], sizeof(short)); + src_ipv4_total_len = htons(src_ipv4_total_len); + + //src_packet_len = src_ipv4_total_len + ETH_LEN; + if(src_ipv4_total_len >= ICMP_SRCPACKET_MAX_LEN){ + icmp_srcpacket_len = ICMP_SRCPACKET_MAX_LEN; + }else{ + icmp_srcpacket_len = src_ipv4_total_len; + } + + icmp_len = icmp_srcpacket_len + ICMP_HEAD_LEN; + ipv4_total_len = icmp_len + IPV4_LEN; + icmpv4_complete_len = IPV4_LEN + icmp_len; + + //format icmp information + memset(&icmpst, 0, sizeof(icmpv4_st)); + memcpy(icmpst.srcPacket, raw_pkt, icmp_srcpacket_len); // + icmpst.type = ICMPV4_UNREACHABLE; + icmpst.type = ICMPV4_PORT_UNREACHABLE; + icmpst.checksum = in_checksum((void*)&icmpst, icmp_len); + + //format ipv4 + memcpy(ipv4, raw_pkt, IPV4_LEN); //copy source data + memcpy(&ipv4[12], &raw_pkt[dip_len], IPV4_IP_LEN); //get sip + memcpy(&ipv4[16], &raw_pkt[sip_len], IPV4_IP_LEN); //get dip + ipv4[9] = ICMP_PROTOCOL_TYPE; //set ipv4 protocol type (0x01 == ICMP) + ipv4_total_len = htons(ipv4_total_len); + memcpy(&ipv4[2], &ipv4_total_len, sizeof(short)); //format ipv4 len + memset(&ipv4[10], 0, sizeof(short)); //empty checksum data + ipv4_checksum = in_checksum(ipv4, IPV4_LEN); //calc ipv4 checksum + memcpy(&ipv4[10], &ipv4_checksum, sizeof(short)); //format checksum + + //format complete icmpv4 packet + memcpy(buf, ipv4, IPV4_LEN); + memcpy(&buf[icmp_start_len], &icmpst, icmp_len); + *len = icmpv4_complete_len; + + return; +} + + +//int format_icmpv6(char *icmp, short icmp_len, char *eth, const char *data){ +static void format_icmpv6(const char *data, char *buf, int *len){ + char checksum_str[ICMPV6_SRCPACKET_MAX_LEN] = {0}; + char ipv6[IPV6_LEN] = {0}; + icmpv6_st icmpst = {0}; + short src_ipv6_total_len = 0; + short icmpv6_complete_len = 0; + short icmp_len = 0; + short icmp_srcpacket_len = 0; + short icmp_start_len = IPV6_LEN; + short checksum_len = 0; + short sip_len = 8; //skip sip start index + short dip_len = 24; //skip dip start index, 16+8 == 24 + short ipv6_ip2 = IPV6_IP_LEN + IPV6_IP_LEN; + short payload_len = 0; + + memcpy(&src_ipv6_total_len, &data[IPV6_IP_PAYLOAD_INDEX], sizeof(short)); //get ipv6_payload_len + src_ipv6_total_len = htons(src_ipv6_total_len) + IPV6_LEN; + + if(src_ipv6_total_len >= ICMPV6_SRCPACKET_MAX_LEN){ + icmp_srcpacket_len = ICMPV6_SRCPACKET_MAX_LEN; + }else{ + icmp_srcpacket_len = src_ipv6_total_len; + } + + icmp_len = icmp_srcpacket_len + ICMP_HEAD_LEN; + icmpv6_complete_len = IPV6_LEN + icmp_len; + checksum_len = icmp_len + IPV6_PESUDO_HEAD_LEN; + payload_len = htons(icmp_len); + + //format ipv6 + memcpy(ipv6, data, IPV6_LEN); //copy source ipv6 data + memcpy(&ipv6[8], &data[dip_len], IPV6_IP_LEN); //get sip + memcpy(&ipv6[24],&data[sip_len], IPV6_IP_LEN); //get dip + memcpy(&ipv6[4], &payload_len, sizeof(short)); //format ipv6 payload + ipv6[6] = ICMPV6_PROTOCAL_TYPE; //format ipv6 protocol (icmpv6 == 0X3a); + + //format icmp + memset(&icmpst, 0, sizeof(icmpv6_st)); + icmpst.type = ICMPV6_UNREACHABLE; + icmpst.code = ICMPV6_PORT_UNREACHABLE; + memcpy(icmpst.srcPacket, data, icmp_srcpacket_len); + + //calc icmpv6 checksum + memcpy(checksum_str, &icmpst, icmp_len); + memcpy(&checksum_str[icmp_len], &ipv6[8], ipv6_ip2); + memcpy(&checksum_str[icmp_len+ipv6_ip2+2], &ipv6[4], sizeof(short)); + checksum_str[icmp_len+ipv6_ip2+7] = ICMPV6_PROTOCAL_TYPE; + icmpst.checksum = in_checksum(checksum_str, checksum_len); + + //format complete icmpv6 packet + memcpy(buf, ipv6, IPV6_LEN); + memcpy(&buf[icmp_start_len], &icmpst, icmp_len); + *len = icmpv6_complete_len; + + return; +} + +static void format_icmp(const char *raw_pkt, char *icmp_buf, int *icmp_len, int ip_type){ + if(IPV4_TYPE == ip_type) { + format_icmpv4(raw_pkt, icmp_buf, icmp_len); + }else{ //IPV6_TYPE + format_icmpv6(raw_pkt, icmp_buf, icmp_len); + } + return; +} + +//int send_icmp_unreach_xxx(const void *raw_pkt, xxxxx) +unsigned char send_icmp_unreachable(const struct streaminfo *a_stream, const void *raw_pkt) +{ + char icmp_buf[ICMP_MAX_LEN]; + int icmp_len = 0; + + if(a_stream->curdir==DIR_S2C || raw_pkt == NULL){ + return 0; + } + + format_icmp((char *)raw_pkt, icmp_buf, &icmp_len, a_stream->addr.addrtype); + return tsg_send_inject_packet(a_stream, SIO_EXCLUDE_THIS_LAYER_HDR, icmp_buf, icmp_len, DIR_S2C); +} + diff --git a/src/tsg_protocol_common.h b/src/tsg_protocol_common.h index 4cdff39..3eb775c 100644 --- a/src/tsg_protocol_common.h +++ b/src/tsg_protocol_common.h @@ -94,6 +94,11 @@ struct monitor_user_region int vlan_id; }; +struct drop_user_para +{ + int send_icmp_unreachable_enable; +}; + struct compile_user_region { int ref_cnt; @@ -103,6 +108,7 @@ struct compile_user_region struct deny_user_region *deny; struct monitor_user_region *mirror; struct Maat_rule_t *result; //XJ default policy + struct drop_user_para *drop_para; void *user_region_para; }; }; @@ -110,5 +116,8 @@ struct compile_user_region int tsg_send_inject_packet(const struct streaminfo *a_stream, enum sapp_inject_opt sio, char *payload, int payload_len, unsigned char raw_route_dir); unsigned char do_action_redirect_dns(const struct streaminfo *a_stream, Maat_rule_t *p_result, struct compile_user_region *user_region, const void *user_data); +unsigned char send_icmp_unreachable(const struct streaminfo *a_stream, const void *raw_pkt); +unsigned char send_tamper_xxx(const struct streaminfo *a_stream, const void *raw_pkt); + #endif diff --git a/src/tsg_rule.cpp b/src/tsg_rule.cpp index 62016a9..233a8bf 100644 --- a/src/tsg_rule.cpp +++ b/src/tsg_rule.cpp @@ -39,7 +39,9 @@ const struct _str2index method2index[TSG_METHOD_TYPE_MAX]={ {TSG_METHOD_TYPE_UNK {TSG_METHOD_TYPE_BLOCK, 5, (char *)"block"}, {TSG_METHOD_TYPE_RESET, 3, (char *)"rst"}, {TSG_METHOD_TYPE_ALERT, 5, (char *)"alert"}, - {TSG_METHOD_TYPE_RATE_LIMIT, 10, (char *)"rate_limit"} + {TSG_METHOD_TYPE_RATE_LIMIT, 10, (char *)"rate_limit"}, + {TSG_METHOD_TYPE_MIRRORED, 8, (char *)"mirrored"}, + {TSG_METHOD_TYPE_TAMPER, 6, (char *)"tamper"} }; //functioned as strdup, for dictator compatible. @@ -950,8 +952,13 @@ static struct compile_user_region *parse_deny_user_region(cJSON *object) get_integer_from_json(object, "bps", &(user_region->deny->bps)); break; case TSG_METHOD_TYPE_DROP: + user_region->drop_para=(struct drop_user_para *)calloc(1, sizeof(struct drop_user_para)); + get_integer_from_json(object, "send_icmp_unreachable", &(user_region->drop_para->send_icmp_unreachable_enable)); + break; case TSG_METHOD_TYPE_RESET: break; + case TSG_METHOD_TYPE_TAMPER: + break; default: break; } diff --git a/src/tsg_tamper.cpp b/src/tsg_tamper.cpp new file mode 100644 index 0000000..b3d100c --- /dev/null +++ b/src/tsg_tamper.cpp @@ -0,0 +1,174 @@ +#include +#include +#include +#include +#include + +#include "tsg_entry.h" +#include "tsg_protocol_common.h" + +#define MTU_LEN 65535 +#define MAC_LEN 6 +#define MAC_LEN_2 ((MAC_LEN)+(MAC_LEN)) +#define ETH_IP_TYPE_LEN 2 +#define ETH_LEN ((MAC_LEN_2)+(ETH_IP_TYPE_LEN)) + +#define IPV4_TYPE 1 //ADDR_TYPE_IPV4 ==1 , 取的enum 0x0800 +#define IPV6_TYPE 2 //ADDR_TYPE_IPV6 ==2 0x86dd +#define TCP_TYPE 0x06 +#define UDP_TYPE 0x11 + +#define IPV4_LEN 20 //ip_len(20) +#define IPV4_PROTOCOL_INDEX 9 //ipv4_protocol_index_len +#define IPV4_TCP_HEAD_LEN_INDEX 32 //ip_len(20) + tcp_head_len_index() +#define ETH_IPV4_IP_UPD_LEN 28 //ip_len(20) + udp_len(8) +#define IPV4_IP_LEN_INDEX 2 //ip_len_index(2) + +#define IPV6_PROTOCOL_INDEX 6 //ipv6_protocol_index(6) +#define IPV6_LEN 40 +#define ETH_IPV6_LEN 40 //ipv6_len(40) +#define IPV6_TCP_OPTION_LEN_INDEX 52 //ipv6_len(40) + tcp_head_len_index(12) +#define IPV6_UDP_PALYLOAD_START_INDEX 48 //ipv6_len(40) + udp_len(8) +#define IPV6_IP_PAYLOAD_INDEX 4 //ipv6_payload_index(4) + +int tamper_calc(char *str, int startlen, int endlen) +{ + int i = 0; + int j = 0; + char temp; + + //最小交换paythod的第2个字节和第四个字节,否则不处理 + if ((endlen - startlen) < 4){ + return STATE_DROPPKT; + } + + //start_len+1 : 因为计算校验和是16bit为单位,这里调换16bit的低8bit。 + for(i = startlen+1; i < endlen; i++){ + for (j = i+2; j < endlen; j++){ + if(str[i] != str[j]){ + temp = str[i]; + str[i] = str[j]; + str[j] = temp; + return STATE_GIVEME; + } + } + } + return STATE_DROPPKT; +} + +int stamp_calc2(char *str, int startlen, int endlen) +{ + int i = 0; + char temp; + + if(endlen - startlen < 4){ + return STATE_DROPPKT; + } + + for(i = startlen; (i < endlen) && (i+3 < endlen); i=i+4){ + printf("ii = %d \n", i); + if(str[i+1] != str[i+3]){ + temp = str[i+1]; + str[i+1] = str[i+3]; + str[i+3] = temp; + return STATE_GIVEME; + } + } + return STATE_DROPPKT; +} + +int tamper_ipv4(const char *packet, char *ret_packet, int *ret_len){ + int packet_len = 0; + int src_ipv4_total_len = 0; + char tcp_head_len; + char protocol_type = packet[IPV4_PROTOCOL_INDEX]; + int payload_start_index = 0; + int tcp_head_all_len = 0; + + //get packet_len + memcpy(&src_ipv4_total_len, &packet[IPV4_IP_LEN_INDEX], sizeof(short)); + packet_len = htons(src_ipv4_total_len); + + if(protocol_type == TCP_TYPE){ + tcp_head_len = ret_packet[IPV4_TCP_HEAD_LEN_INDEX]; + tcp_head_len = ((tcp_head_len>>4)&0x0f)*4; + tcp_head_all_len = tcp_head_len + IPV4_LEN; + if(packet_len == tcp_head_all_len){ + return -1; + } + payload_start_index = IPV4_LEN + tcp_head_len; + }else if(protocol_type == UDP_TYPE){ + if(ETH_IPV4_IP_UPD_LEN == packet_len){ + return -1; + } + payload_start_index = ETH_IPV4_IP_UPD_LEN; + } + + *ret_len = packet_len-payload_start_index+1; + memcpy(ret_packet, &packet[payload_start_index], *ret_len); + return tamper_calc(ret_packet, payload_start_index, packet_len); +} + +//int tamper_ipv6(char *packet, int packet_len){ +int tamper_ipv6(const char *packet, char *ret_packet, int *ret_len){ + int packet_len = 0; + short src_ipv6_total_len = 0; + char tcp_head_len; + char protocol_type = packet[IPV6_PROTOCOL_INDEX]; + int payload_start_index = 0; + int packet_all_len = 0; + + memcpy(&src_ipv6_total_len, &packet[IPV6_IP_PAYLOAD_INDEX], sizeof(short)); //get ipv6_payload_len + packet_len = htons(src_ipv6_total_len) + IPV6_LEN; + *ret_len = packet_len; + + if(protocol_type == TCP_TYPE){ + tcp_head_len = ret_packet[IPV6_TCP_OPTION_LEN_INDEX]; + tcp_head_len = ((tcp_head_len>>4)&0x0f)*4; + packet_all_len = tcp_head_len + IPV6_LEN; + if(packet_len == packet_all_len){ + return -1; + } + payload_start_index = IPV6_LEN + tcp_head_len; + }else if(protocol_type == UDP_TYPE){ + if(IPV6_UDP_PALYLOAD_START_INDEX == packet_len){ + return -1; + } + payload_start_index = IPV6_UDP_PALYLOAD_START_INDEX; + } + + *ret_len = packet_len-payload_start_index+1; + memcpy(ret_packet, &packet[payload_start_index], *ret_len); + return tamper_calc(ret_packet, payload_start_index, packet_len); +} + +static int format_tamper(const char *packet, char *tamper_buf, int *tamper_len, int ip_type){ + int ret = 0; + + if(IPV4_TYPE == ip_type) { + ret = tamper_ipv4((char *)packet, tamper_buf, tamper_len); + }else{ + ret = tamper_ipv6((char *)packet, tamper_buf, tamper_len); + } + + return ret; +} + +unsigned char send_tamper_xxx(const struct streaminfo *a_stream, const void *raw_pkt) +{ + char tamper_buf[MTU_LEN] = {0}; + unsigned char raw_route_dir = 0; + int tamper_len = 0; + int ret = 0; + + ret = format_tamper((char *)raw_pkt, tamper_buf, &tamper_len, a_stream->addr.addrtype); + if (ret < 0){ + return STATE_DROPPKT; + } + + raw_route_dir=(a_stream->curdir==DIR_C2S) ? a_stream->routedir : MESA_dir_reverse(a_stream->routedir); + tsg_send_inject_packet(a_stream, SIO_DEFAULT, tamper_buf, tamper_len, raw_route_dir); + + return STATE_DROPPKT|STATE_DROPME; +} +