Add test case: inject IPv4 based TCP payload packet after recv C2S first payload

This commit is contained in:
luwenpeng
2024-05-21 17:39:16 +08:00
parent 3701fc7361
commit e8c61a1752
24 changed files with 580 additions and 410 deletions

View File

@@ -96,6 +96,7 @@ void packet_set_session_id(struct packet *pkt, uint64_t sess_id);
void packet_set_direction(struct packet *pkt, enum packet_direction dir); void packet_set_direction(struct packet *pkt, enum packet_direction dir);
int packet_is_fragment(const struct packet *pkt); int packet_is_fragment(const struct packet *pkt);
int packet_get_fingerprint(const struct packet *pkt, char *buff, int size);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -2,6 +2,10 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "udp_utils.h"
#include "tcp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "packet_priv.h" #include "packet_priv.h"
#include "marsio.h" #include "marsio.h"
@@ -401,3 +405,65 @@ void packet_append_sid_list(struct packet *pkt, const struct sid_list *list)
PACKET_LOG_WARN("packet origin is not marsio, failed to append sid list"); PACKET_LOG_WARN("packet origin is not marsio, failed to append sid list");
} }
} }
int packet_get_fingerprint(const struct packet *pkt, char *buff, int size)
{
int used = 0;
char tuple_str[256] = {0};
struct tuple6 tuple;
const struct tcphdr *tcp_hdr = NULL;
const struct udphdr *udp_hdr = NULL;
const struct ip *ipv4_hdr = NULL;
const struct ip6_hdr *ipv6_hdr = NULL;
const struct packet_layer *l3_layer = NULL;
const struct packet_layer *l4_layer = NULL;
memset(buff, 0, size);
if (packet_get_innermost_tuple6(pkt, &tuple) != 0)
{
return used;
}
tuple6_to_str(&tuple, tuple_str, sizeof(tuple_str));
used += snprintf(buff + used, size - used, "tuple6: %s, ", tuple_str);
l3_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_L3);
if (l3_layer == NULL || l3_layer->hdr_ptr == NULL)
{
return used;
}
switch (l3_layer->type)
{
case LAYER_TYPE_IPV4:
ipv4_hdr = (const struct ip *)l3_layer->hdr_ptr;
used += snprintf(buff + used, size - used, "ip_ttl: %u, ip_id: %u, ", ipv4_hdr_get_ttl(ipv4_hdr), ipv4_hdr_get_ipid(ipv4_hdr));
break;
case LAYER_TYPE_IPV6:
ipv6_hdr = (const struct ip6_hdr *)l3_layer->hdr_ptr;
used += snprintf(buff + used, size - used, "ip6_hlim: %u, ", ipv6_hdr_get_hop_limit(ipv6_hdr));
break;
default:
break;
}
l4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_L4);
if (l4_layer == NULL || l4_layer->hdr_ptr == NULL)
{
return used;
}
switch (l4_layer->type)
{
case LAYER_TYPE_TCP:
tcp_hdr = (const struct tcphdr *)l4_layer->hdr_ptr;
used += snprintf(buff + used, size - used, "tcp_seq: %u, tcp_ack: %u, tcp_checksum: %u, ", tcp_hdr_get_seq(tcp_hdr), tcp_hdr_get_ack(tcp_hdr), tcp_hdr_get_checksum(tcp_hdr));
break;
case LAYER_TYPE_UDP:
udp_hdr = (const struct udphdr *)l4_layer->hdr_ptr;
used += snprintf(buff + used, size - used, "udp_checksum: %u, ", udp_hdr_get_checksum(udp_hdr));
break;
default:
break;
}
return used;
}

View File

@@ -112,7 +112,7 @@ static void save_packet(const char *work_dir, struct packet *pkt, uint64_t idx)
fwrite(packet_get_data(pkt), 1, len, fp); fwrite(packet_get_data(pkt), 1, len, fp);
fflush(fp); fflush(fp);
fclose(fp); fclose(fp);
PACKET_IO_LOG_DEBUG("save packet to %s", file); PACKET_IO_LOG_STATE("save packet to %s", file);
} }
else else
{ {

View File

@@ -491,7 +491,7 @@ void stellar_print_config(struct stellar_config *config)
CONFIG_LOG_DEBUG("packet_io->nr_threads : %d", io_opts->nr_threads); CONFIG_LOG_DEBUG("packet_io->nr_threads : %d", io_opts->nr_threads);
for (uint16_t i = 0; i < io_opts->nr_threads; i++) for (uint16_t i = 0; i < io_opts->nr_threads; i++)
{ {
CONFIG_LOG_DEBUG("packet_io->cpu_mask[%03d] : %d", i, io_opts->cpu_mask[i]); CONFIG_LOG_DEBUG("packet_io->cpu_mask[%3d] : %d", i, io_opts->cpu_mask[i]);
} }
// ip reassemble config // ip reassemble config

View File

@@ -1,3 +1,4 @@
#include <time.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
@@ -209,7 +210,10 @@ static inline void calc_tcp_fingerprint(struct tcp_fingerprint *finger)
{ {
#define RANGE(rand, start, end) (start + rand % (end - start + 1)) // [start, end] #define RANGE(rand, start, end) (start + rand % (end - start + 1)) // [start, end]
uint64_t random = 0x013579ABCDEF ^ stellar_get_monotonic_time_msec(); struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
uint64_t random = 0x013579ABCDEF ^ time.tv_nsec;
finger->ipid = (uint16_t)(RANGE(random, 32767, 65535)); finger->ipid = (uint16_t)(RANGE(random, 32767, 65535));
finger->ttl = (uint8_t)(RANGE(random, 48, 120)); finger->ttl = (uint8_t)(RANGE(random, 48, 120));
finger->win = (uint16_t)(RANGE(random, 1000, 1460)); finger->win = (uint16_t)(RANGE(random, 1000, 1460));

View File

@@ -1,8 +1,28 @@
add_executable(gtest_inject_tcp_rst packet_injector.cpp gtest_inject_tcp_rst.cpp packet_injector_test_frame.cpp ) add_library(libpacket_injector packet_injector.cpp packet_injector_test_frame.cpp)
target_link_libraries(gtest_inject_tcp_rst core gtest) target_include_directories(libpacket_injector PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(libpacket_injector core gtest)
add_executable(gtest_inject_tcp_rst_after_recv_syn_ack gtest_inject_tcp_rst_after_recv_syn_ack.cpp)
target_link_libraries(gtest_inject_tcp_rst_after_recv_syn_ack libpacket_injector)
add_executable(gtest_inject_tcp_rst_after_recv_sub_ack gtest_inject_tcp_rst_after_recv_sub_ack.cpp)
target_link_libraries(gtest_inject_tcp_rst_after_recv_sub_ack libpacket_injector)
add_executable(gtest_inject_tcp_rst_after_recv_c2s_first_payload gtest_inject_tcp_rst_after_recv_c2s_first_payload.cpp)
target_link_libraries(gtest_inject_tcp_rst_after_recv_c2s_first_payload libpacket_injector)
add_executable(gtest_inject_tcp_rst_after_recv_s2c_first_payload gtest_inject_tcp_rst_after_recv_s2c_first_payload.cpp)
target_link_libraries(gtest_inject_tcp_rst_after_recv_s2c_first_payload libpacket_injector)
add_executable(gtest_inject_tcp_payload_after_recv_c2s_first_payload gtest_inject_tcp_payload_after_recv_c2s_first_payload.cpp)
target_link_libraries(gtest_inject_tcp_payload_after_recv_c2s_first_payload libpacket_injector)
include(GoogleTest) include(GoogleTest)
gtest_discover_tests(gtest_inject_tcp_rst) gtest_discover_tests(gtest_inject_tcp_rst_after_recv_syn_ack)
gtest_discover_tests(gtest_inject_tcp_rst_after_recv_sub_ack)
gtest_discover_tests(gtest_inject_tcp_rst_after_recv_c2s_first_payload)
gtest_discover_tests(gtest_inject_tcp_rst_after_recv_s2c_first_payload)
gtest_discover_tests(gtest_inject_tcp_payload_after_recv_c2s_first_payload)
add_executable(packet_injector packet_injector.cpp) add_executable(packet_injector packet_injector.cpp)
target_link_libraries(packet_injector core gtest) target_link_libraries(packet_injector core gtest)

View File

@@ -40,3 +40,4 @@ curl -v http://http.badssl.selftest.gdnt-cloud.website --resolve "http.badssl.se
| tcp-rst | c2s-packet | 2 | After recv Sub-ACK | Success | | tcp-rst | c2s-packet | 2 | After recv Sub-ACK | Success |
| tcp-rst | c2s-packet | 3 | After recv C2S First-Payload | Success | | tcp-rst | c2s-packet | 3 | After recv C2S First-Payload | Success |
| tcp-rst | s2c-packet | 3 | After recv S2C First-payload | Success | | tcp-rst | s2c-packet | 3 | After recv S2C First-payload | Success |
| tcp-payload | c2s-packet | 3 | After recv C2S First-Payload | Success |

View File

@@ -0,0 +1,62 @@
#include <gtest/gtest.h>
#include "packet_injector_test_frame.h"
TEST(INJECT_IPV4_BASED_TCP_PAYLOAD, AFTER_RECV_C2S_FIRST_PAYLOAD)
{
char current_dir[1024] = {0};
char work_dir[2048] = {0};
char input_dir[2048] = {0};
getcwd(current_dir, sizeof(current_dir));
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP Payload after receiving C2S first payload packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.compares = {
{
.expect_pcap = "expect-192.0.2.110:80-192.0.2.212:54146-1.pcap",
.inject_pcap = "inject-192.0.2.110:80-192.0.2.212:54146-1.pcap",
},
{
.expect_pcap = "expect-192.0.2.110:80-192.0.2.212:54146-2.pcap",
.inject_pcap = "inject-192.0.2.110:80-192.0.2.212:54146-2.pcap",
},
{
.expect_pcap = "expect-192.0.2.110:80-192.0.2.212:54146-3.pcap",
.inject_pcap = "inject-192.0.2.110:80-192.0.2.212:54146-3.pcap",
},
{
.expect_pcap = "expect-192.0.2.212:54146-192.0.2.110:80-4.pcap",
.inject_pcap = "inject-192.0.2.212:54146-192.0.2.110:80-4.pcap",
},
{
.expect_pcap = NULL,
.inject_pcap = NULL,
},
},
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-payload", "-c", "c2s-packet", "-n", "3"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,156 +0,0 @@
#include <gtest/gtest.h>
#include "packet_injector_test_frame.h"
static char current_dir[1024] = {0};
#if 1
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_SYN_ACK)
{
char work_dir[2048] = {0};
char input_dir[2048] = {0};
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_syn_ack");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_syn_ack/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving SYN-ACK packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.c2s_expect_pcap = "expect-192.0.2.211:59942-192.0.2.110:80-1.pcap",
.c2s_output_pcap = "inject-192.0.2.211:59942-192.0.2.110:80-1.pcap",
.s2c_expect_pcap = "expect-192.0.2.110:80-192.0.2.211:59942-2.pcap",
.s2c_output_pcap = "inject-192.0.2.110:80-192.0.2.211:59942-2.pcap",
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "s2c-packet", "-n", "1"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
#endif
#if 1
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_SUB_ACK)
{
char work_dir[2048] = {0};
char input_dir[2048] = {0};
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_sub_ack");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_sub_ack/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving SUB-ACK packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.c2s_expect_pcap = "expect-192.0.2.211:42242-192.0.2.110:80-1.pcap",
.c2s_output_pcap = "inject-192.0.2.211:42242-192.0.2.110:80-1.pcap",
.s2c_expect_pcap = "expect-192.0.2.110:80-192.0.2.211:42242-2.pcap",
.s2c_output_pcap = "inject-192.0.2.110:80-192.0.2.211:42242-2.pcap",
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "c2s-packet", "-n", "2"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
#endif
#if 1
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_C2S_FIRST_PAYLOAD)
{
char work_dir[2048] = {0};
char input_dir[2048] = {0};
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_c2s_first_payload");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_c2s_first_payload/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving C2S first payload packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.c2s_expect_pcap = "expect-192.0.2.211:35116-192.0.2.110:80-1.pcap",
.c2s_output_pcap = "inject-192.0.2.211:35116-192.0.2.110:80-1.pcap",
.s2c_expect_pcap = "expect-192.0.2.110:80-192.0.2.211:35116-2.pcap",
.s2c_output_pcap = "inject-192.0.2.110:80-192.0.2.211:35116-2.pcap",
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "c2s-packet", "-n", "3"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
#endif
#if 1
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_S2C_FIRST_PAYLOAD)
{
char work_dir[2048] = {0};
char input_dir[2048] = {0};
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_s2c_first_payload");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_s2c_first_payload/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving S2C first payload packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.c2s_expect_pcap = "expect-192.0.2.211:54408-192.0.2.110:80-1.pcap",
.c2s_output_pcap = "inject-192.0.2.211:54408-192.0.2.110:80-1.pcap",
.s2c_expect_pcap = "expect-192.0.2.110:80-192.0.2.211:54408-2.pcap",
.s2c_output_pcap = "inject-192.0.2.110:80-192.0.2.211:54408-2.pcap",
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "s2c-packet", "-n", "3"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
#endif
int main(int argc, char **argv)
{
getcwd(current_dir, sizeof(current_dir));
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,54 @@
#include <gtest/gtest.h>
#include "packet_injector_test_frame.h"
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_C2S_FIRST_PAYLOAD)
{
char current_dir[1024] = {0};
char work_dir[2048] = {0};
char input_dir[2048] = {0};
getcwd(current_dir, sizeof(current_dir));
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_c2s_first_payload");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_c2s_first_payload/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving C2S first payload packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.compares = {
{
.expect_pcap = "expect-192.0.2.211:35116-192.0.2.110:80-1.pcap",
.inject_pcap = "inject-192.0.2.211:35116-192.0.2.110:80-1.pcap",
},
{
.expect_pcap = "expect-192.0.2.110:80-192.0.2.211:35116-2.pcap",
.inject_pcap = "inject-192.0.2.110:80-192.0.2.211:35116-2.pcap",
},
{
.expect_pcap = NULL,
.inject_pcap = NULL,
},
},
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "c2s-packet", "-n", "3"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,54 @@
#include <gtest/gtest.h>
#include "packet_injector_test_frame.h"
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_S2C_FIRST_PAYLOAD)
{
char current_dir[1024] = {0};
char work_dir[2048] = {0};
char input_dir[2048] = {0};
getcwd(current_dir, sizeof(current_dir));
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_s2c_first_payload");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_s2c_first_payload/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving S2C first payload packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.compares = {
{
.expect_pcap = "expect-192.0.2.211:54408-192.0.2.110:80-1.pcap",
.inject_pcap = "inject-192.0.2.211:54408-192.0.2.110:80-1.pcap",
},
{
.expect_pcap = "expect-192.0.2.110:80-192.0.2.211:54408-2.pcap",
.inject_pcap = "inject-192.0.2.110:80-192.0.2.211:54408-2.pcap",
},
{
.expect_pcap = NULL,
.inject_pcap = NULL,
},
},
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "s2c-packet", "-n", "3"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,54 @@
#include <gtest/gtest.h>
#include "packet_injector_test_frame.h"
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_SUB_ACK)
{
char current_dir[1024] = {0};
char work_dir[2048] = {0};
char input_dir[2048] = {0};
getcwd(current_dir, sizeof(current_dir));
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_sub_ack");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_sub_ack/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving SUB-ACK packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.compares = {
{
.expect_pcap = "expect-192.0.2.211:42242-192.0.2.110:80-1.pcap",
.inject_pcap = "inject-192.0.2.211:42242-192.0.2.110:80-1.pcap",
},
{
.expect_pcap = "expect-192.0.2.110:80-192.0.2.211:42242-2.pcap",
.inject_pcap = "inject-192.0.2.110:80-192.0.2.211:42242-2.pcap",
},
{
.expect_pcap = NULL,
.inject_pcap = NULL,
},
},
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "c2s-packet", "-n", "2"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,54 @@
#include <gtest/gtest.h>
#include "packet_injector_test_frame.h"
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_SYN_ACK)
{
char current_dir[1024] = {0};
char work_dir[2048] = {0};
char input_dir[2048] = {0};
getcwd(current_dir, sizeof(current_dir));
snprintf(work_dir, sizeof(work_dir), "%s/%s", current_dir, "inject_ipv4_based_tcp_rst_after_recv_syn_ack");
snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_rst_after_recv_syn_ack/test/");
struct packet_injector_case test = {
// descriptor
.finish_clean_work_dir = 0,
.descriptor = "Inject IPv4 based TCP RST after receiving SYN-ACK packet.",
.work_dir = work_dir,
// prefix
.input_prefix = input_dir,
// input pcap
.input_pcap = "input.pcap",
// compare
.compares = {
{
.expect_pcap = "expect-192.0.2.211:59942-192.0.2.110:80-1.pcap",
.inject_pcap = "inject-192.0.2.211:59942-192.0.2.110:80-1.pcap",
},
{
.expect_pcap = "expect-192.0.2.110:80-192.0.2.211:59942-2.pcap",
.inject_pcap = "inject-192.0.2.110:80-192.0.2.211:59942-2.pcap",
},
{
.expect_pcap = NULL,
.inject_pcap = NULL,
},
},
// packet injector command
.packet_injector_cmd = {"./packet_injector", "-t", "tcp-rst", "-c", "s2c-packet", "-n", "1"},
.diff_skip_pattern = "-I frame.time -I frame.time_epoch -I ip.id -I ip.ttl -I ip.checksum -I tcp.checksum -I tcp.window_size",
};
packet_injector_test_frame_run(&test);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -17,10 +17,8 @@
#include "stellar/tuple.h" #include "stellar/tuple.h"
#include "stellar/session_mq.h" #include "stellar/session_mq.h"
#define MOCK_PLUGIN_LOG_DEBUG(format, ...) LOG_DEBUG("mock plugin", format, ##__VA_ARGS__)
/****************************************************************************** /******************************************************************************
* gmock plugin manager * packet_injector
******************************************************************************/ ******************************************************************************/
enum condition enum condition
@@ -50,157 +48,7 @@ struct inject_rule
uint64_t count_num; uint64_t count_num;
} rule; } rule;
static void inject_packet_plugin(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env) #define INJECT_PACKET_PLUGIN_LOG_DEBUG(format, ...) LOG_DEBUG("inject packet plugin", format, ##__VA_ARGS__)
{
char buffer[1024] = {0};
struct inject_rule *p_rule = &rule;
// struct packet *pkt = (struct packet *)msg;
const struct tuple6 *tuple = session_get_tuple6(sess);
if (p_rule->ip_type == 4 &&
memcmp(&tuple->src_addr.v4, &p_rule->v4, sizeof(struct in_addr)) &&
memcmp(&tuple->dst_addr.v4, &p_rule->v4, sizeof(struct in_addr)))
{
return;
}
if (p_rule->ip_type == 6 &&
memcmp(&tuple->src_addr.v6, &p_rule->v6, sizeof(struct in6_addr)) &&
memcmp(&tuple->dst_addr.v6, &p_rule->v6, sizeof(struct in6_addr)))
{
return;
}
if (p_rule->port != 0 && tuple->src_port != p_rule->port && tuple->dst_port != p_rule->port)
{
return;
}
if (session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_INJECTED_PACKETS_SUCCESS) > 0 ||
session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_INJECTED_PACKETS_SUCCESS) > 0)
{
return;
}
if (p_rule->count_dir == AFTER_RECV_C2S_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
{
return;
}
if (p_rule->count_dir == AFTER_RECV_S2C_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
{
return;
}
switch (p_rule->inject_type)
{
case INJECT_TYPE_TCP_RST:
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0);
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0);
session_set_discard(sess);
break;
case INJECT_TYPE_TCP_FIN:
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_C2S) > 0);
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_S2C) > 0);
session_set_discard(sess);
break;
case INJECT_TYPE_TCP_PAYLOAD:
snprintf(buffer, sizeof(buffer), "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s", 5 + 5 + 2, "Hello");
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, buffer, strlen(buffer)) > 0); // inject payload to client
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, "World\r\n", 7) > 0); // inject payload to client
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0); // inject RST to client
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0); // inject RST to server
session_set_discard(sess);
break;
case INJECT_TYPE_UDP_PAYLOAD:
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_C2S, "Hello Server", 12) > 0);
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, "Hello Client", 12) > 0);
session_set_discard(sess);
break;
case INJECT_TYPE_CTRL_MSG:
// TOOD
break;
default:
break;
}
}
/******************************************************************************
* mock plugin manager
******************************************************************************/
void *plugin_manager_new_ctx(struct session *sess, void *plugin_env)
{
return NULL;
}
void plugin_manager_free_ctx(struct session *sess, void *ctx, void *plugin_env)
{
char buff[4096] = {0};
session_to_json(sess, buff, sizeof(buff));
MOCK_PLUGIN_LOG_DEBUG("=> session: %s", buff);
}
/******************************************************************************
* main
******************************************************************************/
// curl -v http://http.badssl.selftest.gdnt-cloud.website --resolve "http.badssl.selftest.gdnt-cloud.website:80:192.0.2.110"
static const char *log_config_file = "./conf/log.toml";
static const char *stellar_config_file = "./conf/stellar.toml";
static void signal_handler(int signo)
{
if (signo == SIGINT)
{
STELLAR_LOG_STATE("SIGINT received, notify threads to exit !!!");
ATOMIC_SET(&runtime->need_exit, 1);
}
if (signo == SIGQUIT)
{
STELLAR_LOG_STATE("SIGQUIT received, notify threads to exit !!!");
ATOMIC_SET(&runtime->need_exit, 1);
}
if (signo == SIGTERM)
{
STELLAR_LOG_STATE("SIGTERM received, notify threads to exit !!!");
ATOMIC_SET(&runtime->need_exit, 1);
}
if (signo == SIGHUP)
{
STELLAR_LOG_STATE("SIGHUP received, reload log level !!!");
log_reload_level(log_config_file);
}
}
static int all_session_have_freed(void)
{
for (int i = 0; i < config->io_opts.nr_threads; i++)
{
struct session_manager *sess_mgr = runtime->threads[i].sess_mgr;
struct session_manager_stat *sess_stat = session_manager_stat(sess_mgr);
if (ATOMIC_READ(&sess_stat->curr_nr_tcp_sess_used) != 0)
{
return 0;
}
if (ATOMIC_READ(&sess_stat->curr_nr_udp_sess_used) != 0)
{
return 0;
}
}
return 1;
}
static int all_stat_have_output(void)
{
static int count = 0;
if (runtime->stat_last_output_ts == stellar_get_monotonic_time_msec())
{
count++;
}
return count == 2;
}
static void usage(char *cmd) static void usage(char *cmd)
{ {
@@ -219,7 +67,7 @@ static void usage(char *cmd)
printf("\n"); printf("\n");
} }
static int parse_cmdline(int argc, char **argv, struct inject_rule *rule) static int packet_injector_on_init(int argc, char **argv, struct inject_rule *rule)
{ {
memset(rule, 0, sizeof(struct inject_rule)); memset(rule, 0, sizeof(struct inject_rule));
@@ -342,9 +190,155 @@ static int parse_cmdline(int argc, char **argv, struct inject_rule *rule)
return 0; return 0;
} }
int inject_packet_main(int argc, char **argv) static void packet_injector_on_msg(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
{ {
if (parse_cmdline(argc, argv, &rule) != 0) char buffer[1024] = {0};
struct inject_rule *p_rule = &rule;
// struct packet *pkt = (struct packet *)msg;
const struct tuple6 *tuple = session_get_tuple6(sess);
if (p_rule->ip_type == 4 &&
memcmp(&tuple->src_addr.v4, &p_rule->v4, sizeof(struct in_addr)) &&
memcmp(&tuple->dst_addr.v4, &p_rule->v4, sizeof(struct in_addr)))
{
return;
}
if (p_rule->ip_type == 6 &&
memcmp(&tuple->src_addr.v6, &p_rule->v6, sizeof(struct in6_addr)) &&
memcmp(&tuple->dst_addr.v6, &p_rule->v6, sizeof(struct in6_addr)))
{
return;
}
if (p_rule->port != 0 && tuple->src_port != p_rule->port && tuple->dst_port != p_rule->port)
{
return;
}
if (session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_INJECTED_PACKETS_SUCCESS) > 0 ||
session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_INJECTED_PACKETS_SUCCESS) > 0)
{
return;
}
if (p_rule->count_dir == AFTER_RECV_C2S_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_C2S, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
{
return;
}
if (p_rule->count_dir == AFTER_RECV_S2C_N_PACKET && session_get_stat(sess, FLOW_DIRECTION_S2C, STAT_RAW_PACKETS_RECEIVED) != p_rule->count_num)
{
return;
}
switch (p_rule->inject_type)
{
case INJECT_TYPE_TCP_RST:
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0);
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0);
session_set_discard(sess);
break;
case INJECT_TYPE_TCP_FIN:
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_C2S) > 0);
EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_S2C) > 0);
session_set_discard(sess);
break;
case INJECT_TYPE_TCP_PAYLOAD:
snprintf(buffer, sizeof(buffer), "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s", 5 + 5 + 2, "Hello");
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, buffer, strlen(buffer)) > 0); // inject payload to client
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, "World\r\n", 7) > 0); // inject payload to client
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0); // inject RST to client
EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0); // inject RST to server
session_set_discard(sess);
break;
case INJECT_TYPE_UDP_PAYLOAD:
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_C2S, "Hello Server", 12) > 0);
EXPECT_TRUE(stellar_inject_payload(sess, FLOW_DIRECTION_S2C, "Hello Client", 12) > 0);
session_set_discard(sess);
break;
case INJECT_TYPE_CTRL_MSG:
// TOOD
break;
default:
break;
}
}
static void *packet_injector_on_sess_new(struct session *sess, void *plugin_env)
{
return NULL;
}
static void packet_injector_on_sess_free(struct session *sess, void *ctx, void *plugin_env)
{
char buff[4096] = {0};
session_to_json(sess, buff, sizeof(buff));
INJECT_PACKET_PLUGIN_LOG_DEBUG("=> session: %s", buff);
}
/******************************************************************************
* main
******************************************************************************/
static const char *log_config_file = "./conf/log.toml";
static const char *stellar_config_file = "./conf/stellar.toml";
static void signal_handler(int signo)
{
if (signo == SIGINT)
{
STELLAR_LOG_STATE("SIGINT received, notify threads to exit !!!");
ATOMIC_SET(&runtime->need_exit, 1);
}
if (signo == SIGQUIT)
{
STELLAR_LOG_STATE("SIGQUIT received, notify threads to exit !!!");
ATOMIC_SET(&runtime->need_exit, 1);
}
if (signo == SIGTERM)
{
STELLAR_LOG_STATE("SIGTERM received, notify threads to exit !!!");
ATOMIC_SET(&runtime->need_exit, 1);
}
if (signo == SIGHUP)
{
STELLAR_LOG_STATE("SIGHUP received, reload log level !!!");
log_reload_level(log_config_file);
}
}
static int all_session_have_freed(void)
{
for (int i = 0; i < config->io_opts.nr_threads; i++)
{
struct session_manager *sess_mgr = runtime->threads[i].sess_mgr;
struct session_manager_stat *sess_stat = session_manager_stat(sess_mgr);
if (ATOMIC_READ(&sess_stat->curr_nr_tcp_sess_used) != 0)
{
return 0;
}
if (ATOMIC_READ(&sess_stat->curr_nr_udp_sess_used) != 0)
{
return 0;
}
}
return 1;
}
static int all_stat_have_output(void)
{
static int count = 0;
if (runtime->stat_last_output_ts == stellar_get_monotonic_time_msec())
{
count++;
}
return count == 2;
}
int packet_injector_main(int argc, char **argv)
{
if (packet_injector_on_init(argc, argv, &rule) != 0)
{ {
return -1; return -1;
} }
@@ -400,12 +394,12 @@ int inject_packet_main(int argc, char **argv)
goto error_out; goto error_out;
} }
sess_plug_id = stellar_session_plugin_register(&st, plugin_manager_new_ctx, plugin_manager_free_ctx, NULL); sess_plug_id = stellar_session_plugin_register(&st, packet_injector_on_sess_new, packet_injector_on_sess_free, NULL);
tcp_topic_id = stellar_session_mq_get_topic_id(&st, TOPIC_TCP); tcp_topic_id = stellar_session_mq_get_topic_id(&st, TOPIC_TCP);
udp_topic_id = stellar_session_mq_get_topic_id(&st, TOPIC_UDP); udp_topic_id = stellar_session_mq_get_topic_id(&st, TOPIC_UDP);
stellar_session_mq_subscribe(&st, tcp_topic_id, inject_packet_plugin, sess_plug_id); stellar_session_mq_subscribe(&st, tcp_topic_id, packet_injector_on_msg, sess_plug_id);
stellar_session_mq_subscribe(&st, udp_topic_id, inject_packet_plugin, sess_plug_id); stellar_session_mq_subscribe(&st, udp_topic_id, packet_injector_on_msg, sess_plug_id);
if (stellar_thread_init(runtime, config) != 0) if (stellar_thread_init(runtime, config) != 0)
{ {
@@ -452,5 +446,5 @@ error_out:
int __attribute__((weak)) main(int argc, char **argv) int __attribute__((weak)) main(int argc, char **argv)
{ {
return inject_packet_main(argc, argv); return packet_injector_main(argc, argv);
} }

View File

@@ -78,58 +78,44 @@ static int replace_file_string(const char *file, const char *old_str, const char
return 0; return 0;
} }
static void expect_cmp_inject(const char *work_dir, static void expect_cmp_inject(const char *expect_pcap_file, const char *inject_pcap_file, const char *diff_skip_pattern, int idx)
const char *expect_dir_abs_path, const char *expect_pcap_file,
const char *output_dir_abs_path, const char *output_pcap_file,
const char *diff_skip_pattern, const char *flow_dir)
{ {
struct stat s; struct stat s;
char expect_pcap_file_abs_path[1024] = {0}; char expect_pcap_json[1024] = {0};
char output_pcap_file_abs_path[1024] = {0}; char inject_pcap_json[1024] = {0};
char expect_json_file_abs_path[1024] = {0}; char diff_json_txt[1024] = {0};
char output_json_file_abs_path[1024] = {0};
char diff_txt_file_abs_path[1024] = {0};
// absulute path snprintf(expect_pcap_json, sizeof(expect_pcap_json), "expect_pcap_%d.json", idx);
snprintf(expect_pcap_file_abs_path, sizeof(expect_pcap_file_abs_path), "%s/%s", expect_dir_abs_path, expect_pcap_file); snprintf(inject_pcap_json, sizeof(inject_pcap_json), "inject_pcap_%d.json", idx);
snprintf(output_pcap_file_abs_path, sizeof(output_pcap_file_abs_path), "%s/%s", output_dir_abs_path, output_pcap_file); snprintf(diff_json_txt, sizeof(diff_json_txt), "json_diff_%d.txt", idx);
snprintf(expect_json_file_abs_path, sizeof(expect_json_file_abs_path), "%s/expect_%s.json", work_dir, flow_dir);
snprintf(output_json_file_abs_path, sizeof(output_json_file_abs_path), "%s/output_%s.json", work_dir, flow_dir);
snprintf(diff_txt_file_abs_path, sizeof(diff_txt_file_abs_path), "%s/diff_%s.txt", work_dir, flow_dir);
// check pcap file size stat(expect_pcap_file, &s);
stat(expect_pcap_file_abs_path, &s);
EXPECT_TRUE(s.st_size > 0); EXPECT_TRUE(s.st_size > 0);
stat(output_pcap_file_abs_path, &s); stat(inject_pcap_file, &s);
EXPECT_TRUE(s.st_size > 0); EXPECT_TRUE(s.st_size > 0);
// tcpdump printf("\033[32m tcpdump read expect pcap (%s) \033[0m\n", expect_pcap_file);
printf("\033[32m tcpdump read [%s] expect pcap (%s) \033[0m\n", flow_dir, expect_pcap_file); system_cmd("tcpdump -r %s", expect_pcap_file);
system_cmd("tcpdump -r %s", expect_pcap_file_abs_path);
printf("\033[32m tcpdump read [%s] output pcap (%s) \033[0m\n", flow_dir, output_pcap_file); printf("\033[32m tcpdump read inject pcap (%s) \033[0m\n", inject_pcap_file);
system_cmd("tcpdump -r %s", output_pcap_file_abs_path); system_cmd("tcpdump -r %s", inject_pcap_file);
// tshark system_cmd("tshark -r %s -T json | jq >> %s", expect_pcap_file, expect_pcap_json);
system_cmd("tshark -r %s -T json | jq >> %s", expect_pcap_file_abs_path, expect_json_file_abs_path); system_cmd("tshark -r %s -T json | jq >> %s", inject_pcap_file, inject_pcap_json);
system_cmd("tshark -r %s -T json | jq >> %s", output_pcap_file_abs_path, output_json_file_abs_path);
// check json file size stat(expect_pcap_json, &s);
stat(expect_json_file_abs_path, &s);
EXPECT_TRUE(s.st_size > 0); EXPECT_TRUE(s.st_size > 0);
stat(output_json_file_abs_path, &s); stat(inject_pcap_json, &s);
EXPECT_TRUE(s.st_size > 0); EXPECT_TRUE(s.st_size > 0);
// diff system_cmd("diff %s %s %s >> %s", diff_skip_pattern, expect_pcap_json, inject_pcap_json, diff_json_txt);
system_cmd("diff %s %s %s >> %s", diff_skip_pattern, expect_json_file_abs_path, output_json_file_abs_path, diff_txt_file_abs_path);
// check diff file size stat(diff_json_txt, &s);
stat(diff_txt_file_abs_path, &s);
EXPECT_TRUE(s.st_size == 0); EXPECT_TRUE(s.st_size == 0);
} }
extern int inject_packet_main(int argc, char **argv); extern int packet_injector_main(int argc, char **argv);
static int args_len(const char **args) static int args_len(const char **args)
{ {
@@ -147,67 +133,41 @@ void packet_injector_test_frame_run(struct packet_injector_case *test)
printf("\033[32mTest: %s\033[0m\n", test->descriptor); printf("\033[32mTest: %s\033[0m\n", test->descriptor);
printf("\033[32m ============================================= \033[0m\n"); printf("\033[32m ============================================= \033[0m\n");
char config_file_abs_path[1024] = {0};
char input_dir_abs_path[1024] = {0};
char output_dir_abs_path[1024] = {0};
char expect_dir_abs_path[1024] = {0};
char log_dir_abs_path[1024] = {0};
// absulute path
snprintf(config_file_abs_path, sizeof(config_file_abs_path), "%s/conf/stellar.toml", test->work_dir);
snprintf(input_dir_abs_path, sizeof(input_dir_abs_path), "%s/input/", test->work_dir);
snprintf(output_dir_abs_path, sizeof(output_dir_abs_path), "%s/output/", test->work_dir);
snprintf(expect_dir_abs_path, sizeof(expect_dir_abs_path), "%s/expect/", test->work_dir);
snprintf(log_dir_abs_path, sizeof(log_dir_abs_path), "%s/log/", test->work_dir);
// create directory // create directory
char dumpfile_dir[1024] = {0};
snprintf(dumpfile_dir, sizeof(dumpfile_dir), "%s/input/", test->work_dir);
system_cmd("rm -rf %s", test->work_dir); system_cmd("rm -rf %s", test->work_dir);
system_cmd("mkdir -p %s", input_dir_abs_path); system_cmd("mkdir -p %s", dumpfile_dir);
system_cmd("mkdir -p %s", output_dir_abs_path); system_cmd("mkdir -p %s/log/", test->work_dir);
system_cmd("mkdir -p %s", expect_dir_abs_path);
system_cmd("mkdir -p %s", log_dir_abs_path);
// copy file to work directory // copy file to work directory
if (test->c2s_expect_pcap) for (int i = 0; i < MAX_COMPARISON; i++)
{ {
system_cmd("cp %s/%s %s", test->input_prefix, test->c2s_expect_pcap, expect_dir_abs_path); if (test->compares[i].expect_pcap)
}
if (test->s2c_expect_pcap)
{ {
system_cmd("cp %s/%s %s", test->input_prefix, test->s2c_expect_pcap, expect_dir_abs_path); system_cmd("cp %s/%s %s", test->input_prefix, test->compares[i].expect_pcap, test->work_dir);
} }
system_cmd("cp %s/%s %s", test->input_prefix, test->input_pcap, input_dir_abs_path); }
system_cmd("cp %s/%s %s", test->input_prefix, test->input_pcap, dumpfile_dir);
system_cmd("cp -r conf %s/", test->work_dir); system_cmd("cp -r conf %s/", test->work_dir);
system_cmd("cp packet_injector %s/", test->work_dir);
// replace config file
char temp[2048] = {0};
snprintf(temp, sizeof(temp), "dumpfile_dir = \"%s\"", input_dir_abs_path);
EXPECT_TRUE(replace_file_string(config_file_abs_path, "mode = marsio", "mode = dumpfile") == 0);
EXPECT_TRUE(replace_file_string(config_file_abs_path, "dumpfile_dir = \"/tmp/dumpfile/\"", temp) == 0);
// run packet injector // run packet injector
char cwd[1024]; char cwd[2048] = {0};
char temp[2048] = {0};
getcwd(cwd, sizeof(cwd)); getcwd(cwd, sizeof(cwd));
chdir(test->work_dir); chdir(test->work_dir);
inject_packet_main(args_len(test->packet_injector_cmd), (char **)test->packet_injector_cmd); snprintf(temp, sizeof(temp), "dumpfile_dir = \"%s\"", dumpfile_dir);
EXPECT_TRUE(replace_file_string("./conf/stellar.toml", "mode = marsio", "mode = dumpfile") == 0);
EXPECT_TRUE(replace_file_string("./conf/stellar.toml", "dumpfile_dir = \"/tmp/dumpfile/\"", temp) == 0);
packet_injector_main(args_len(test->packet_injector_cmd), (char **)test->packet_injector_cmd);
// compare pcap // compare pcap
if (test->c2s_output_pcap && test->c2s_expect_pcap) for (int i = 0; i < MAX_COMPARISON; i++)
{ {
system_cmd("mv %s/%s %s", test->work_dir, test->c2s_output_pcap, output_dir_abs_path); if (test->compares[i].expect_pcap && test->compares[i].inject_pcap)
expect_cmp_inject(test->work_dir, {
expect_dir_abs_path, test->c2s_expect_pcap, expect_cmp_inject(test->compares[i].expect_pcap, test->compares[i].inject_pcap, test->diff_skip_pattern, i + 1);
output_dir_abs_path, test->c2s_output_pcap,
test->diff_skip_pattern, "C2S");
} }
if (test->s2c_output_pcap && test->s2c_expect_pcap)
{
system_cmd("mv %s/%s %s", test->work_dir, test->s2c_output_pcap, output_dir_abs_path);
expect_cmp_inject(test->work_dir,
expect_dir_abs_path, test->s2c_expect_pcap,
output_dir_abs_path, test->s2c_output_pcap,
test->diff_skip_pattern, "S2C");
} }
// clean work directory // clean work directory

View File

@@ -6,6 +6,8 @@ extern "C"
{ {
#endif #endif
#define MAX_COMPARISON 16
struct packet_injector_case struct packet_injector_case
{ {
// descriptor // descriptor
@@ -20,11 +22,11 @@ struct packet_injector_case
const char *input_pcap; const char *input_pcap;
// compare // compare
const char *c2s_expect_pcap; struct
const char *c2s_output_pcap; {
const char *expect_pcap;
const char *s2c_expect_pcap; const char *inject_pcap;
const char *s2c_output_pcap; } compares[MAX_COMPARISON];
// packet injector command // packet injector command
const char *packet_injector_cmd[16]; const char *packet_injector_cmd[16];