summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryangwenlin <[email protected]>2022-01-17 14:33:52 +0800
committeryangwenlin <[email protected]>2022-01-17 14:33:52 +0800
commitb3ad7f4056226be3c51ec4bce84ee77d215a1a7d (patch)
tree24a95b76546f72f9f1315252a8f452d357f200d2
parentb1239d556e1f930417477a14fe0065197c3bd286 (diff)
TSG-9308:修复在封装icmp获取raw_pkt可能不是从IP层来数据包,导致后续处理段错误问题v5.4.29
-rw-r--r--src/tsg_action.cpp2
-rw-r--r--src/tsg_icmp.cpp66
-rw-r--r--src/tsg_protocol_common.h2
3 files changed, 46 insertions, 24 deletions
diff --git a/src/tsg_action.cpp b/src/tsg_action.cpp
index ea7e942..ee05eba 100644
--- a/src/tsg_action.cpp
+++ b/src/tsg_action.cpp
@@ -554,7 +554,7 @@ static unsigned char do_action_drop(const struct streaminfo *a_stream, Maat_rule
{
if(user_region!=NULL && user_region->deny!=NULL && user_region->deny->type==TSG_DENY_TYPE_SEND_ICMP)
{
- send_icmp_unreachable(a_stream, a_packet);
+ send_icmp_unreachable(a_stream);
}
switch(protocol)
diff --git a/src/tsg_icmp.cpp b/src/tsg_icmp.cpp
index 71594de..bcdd170 100644
--- a/src/tsg_icmp.cpp
+++ b/src/tsg_icmp.cpp
@@ -25,6 +25,7 @@
//icmp
#define ICMP_HEADR_BYTE_LEN 8
#define ICMP_MAX_LEN 2048
+#define ETHERNET_BYTE_LEN 14
//icmpv4
#define IPV4_HEADR_BYTE_LEN 20
@@ -90,7 +91,7 @@ static short in_checksum(void *pkg, int size)
}
-static void four_byte_alignment(short *icmp_len, short *icmp_checksum_len){
+static void four_byte_alignment(unsigned short *icmp_len, unsigned short *icmp_checksum_len){
short temp = 0;
temp = *icmp_len % 4;
@@ -121,13 +122,13 @@ static void four_byte_alignment(short *icmp_len, short *icmp_checksum_len){
static void format_icmpv4(const char *raw_pkt, char *ret_icmpv4, int *ret_len){
icmp_st icmp = {0};
char ipv4_headr[IPV4_HEADR_BYTE_LEN] = {0};
- short raw_ipv4_total_len = 0;
- short icmpv4_len = 0;
- short ipv4_total_len = 0;
- short ipv4_checksum = 0;
- short icmp_len = 0;
- short icmp_original_data_len = 0;
- short icmp_start_len = IPV4_HEADR_BYTE_LEN;
+ unsigned short raw_ipv4_total_len = 0;
+ unsigned short icmpv4_len = 0;
+ unsigned short ipv4_total_len = 0;
+ unsigned short ipv4_checksum = 0;
+ unsigned short icmp_len = 0;
+ unsigned short icmp_original_data_len = 0;
+ unsigned short icmp_start_len = IPV4_HEADR_BYTE_LEN;
memcpy(&raw_ipv4_total_len, &raw_pkt[IPV4_TOTAL_LEN_INDEX], IPV4_TOTAL_BYTE_LEN);
raw_ipv4_total_len = htons(raw_ipv4_total_len);
@@ -229,14 +230,14 @@ static void format_icmpv6(const char *raw_pkt, char *ret_icmpv6, int *ret_len){
icmp_st icmp = {0};
char icmp_checksum_buf[ICMPV6_MTU] = {0};
char ipv6_headr[IPV6_HEADR_BYTE_LEN] = {0};
- short ipv6_payload_len = 0;
- short raw_ipv6_payload_len = 0;
- short raw_pkt_len = 0;
- short icmpv6_len = 0;
- short icmp_len = 0;
- short icmp_original_data_len = 0;
- short icmp_checksum_len = 0;
- int upper_layer_packet_len = 0;
+ unsigned short ipv6_payload_len = 0;
+ unsigned short raw_ipv6_payload_len = 0;
+ unsigned short raw_pkt_len = 0;
+ unsigned short icmpv6_len = 0;
+ unsigned short icmp_len = 0;
+ unsigned short icmp_original_data_len = 0;
+ unsigned short icmp_checksum_len = 0;
+ unsigned int upper_layer_packet_len = 0;
memcpy(&raw_ipv6_payload_len, &raw_pkt[IPV6_PAYLOAD_INDEX], IPV6_PAYLOAD_BYTE_LEN); //get ipv6_payload_len
raw_pkt_len = ntohs(raw_ipv6_payload_len) + IPV6_HEADR_BYTE_LEN;
@@ -292,21 +293,42 @@ static void format_icmp(const char *raw_pkt, char *icmp_buf, int *icmp_len, int
return;
}
-unsigned char send_icmp_unreachable(const struct streaminfo *a_stream, const void *raw_pkt)
+/* get option from raw packet.
+ * example:
+ * 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!
+ * }
+ */
+
+unsigned char send_icmp_unreachable(const struct streaminfo *a_stream)
{
char icmp_buf[ICMP_MAX_LEN] = {0};
char debug_buf[512] = {0};
int icmp_len = 0;
-
- if((a_stream==NULL)||(raw_pkt==NULL)){
+ int get_rawpkt_ret = 0;
+ void *raw_pkt;
+
+ if(a_stream==NULL){
+ MESA_handle_runtime_log(g_tsg_para.logger,
+ RLOG_LV_DEBUG,
+ __FUNCTION__,
+ "a_stream is NULL");
return STATE_DROPPKT;
}
- format_icmp((char *)raw_pkt, icmp_buf, &icmp_len, a_stream->addr.addrtype);
+ get_rawpkt_ret = get_rawpkt_opt_from_streaminfo(a_stream, RAW_PKT_GET_DATA, &raw_pkt);
+
+ format_icmp((char *)raw_pkt+ETHERNET_BYTE_LEN, icmp_buf, &icmp_len, a_stream->addr.addrtype);
if (0 == tsg_send_inject_packet(a_stream, SIO_EXCLUDE_THIS_LAYER_HDR, icmp_buf, icmp_len, MESA_dir_reverse(a_stream->routedir))){
- sprintf(debug_buf, "Addr: %s, send_icmp_unreachable sucess, raw_pkt %p, icmp_buf %p, icmp_len %d", PRINTADDR(a_stream, g_tsg_para.level), raw_pkt, icmp_buf, icmp_len);
+ sprintf(debug_buf, "Addr: %s, send sucess, get_rawpkt_ret %d, icmp_buf %p, icmp_len %d", PRINTADDR(a_stream, g_tsg_para.level), get_rawpkt_ret, icmp_buf, icmp_len);
}else{
- sprintf(debug_buf, "Addr: %s, send_icmp_unreachable failed, raw_pkt %p, icmp_buf %p, icmp_len %d", PRINTADDR(a_stream, g_tsg_para.level), raw_pkt, icmp_buf, icmp_len);
+ sprintf(debug_buf, "Addr: %s, send failed, get_rawpkt_ret %d, icmp_buf %p, icmp_len %d", PRINTADDR(a_stream, g_tsg_para.level), get_rawpkt_ret, icmp_buf, icmp_len);
}
MESA_handle_runtime_log(g_tsg_para.logger,
diff --git a/src/tsg_protocol_common.h b/src/tsg_protocol_common.h
index c941ae2..a7d1959 100644
--- a/src/tsg_protocol_common.h
+++ b/src/tsg_protocol_common.h
@@ -135,7 +135,7 @@ 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_icmp_unreachable(const struct streaminfo *a_stream);
int send_tamper_xxx(const struct streaminfo *a_stream, long *tamper_count, const void *raw_pkt);
#endif