From e8c61a175298d827537591851b6561d81bcc428d Mon Sep 17 00:00:00 2001 From: luwenpeng Date: Tue, 21 May 2024 17:39:16 +0800 Subject: [PATCH] Add test case: inject IPv4 based TCP payload packet after recv C2S first payload --- src/packet/packet_priv.h | 1 + src/packet/packet_utils.cpp | 66 ++++ src/packet_io/dumpfile_io.cpp | 2 +- src/stellar/config.cpp | 2 +- src/stellar/inject.cpp | 6 +- test/CMakeLists.txt | 26 +- test/README.md | 3 +- ...p_payload_after_recv_c2s_first_payload.cpp | 62 ++++ test/gtest_inject_tcp_rst.cpp | 156 --------- ...t_tcp_rst_after_recv_c2s_first_payload.cpp | 54 +++ ...t_tcp_rst_after_recv_s2c_first_payload.cpp | 54 +++ ...test_inject_tcp_rst_after_recv_sub_ack.cpp | 54 +++ ...test_inject_tcp_rst_after_recv_syn_ack.cpp | 54 +++ test/packet_injector.cpp | 316 +++++++++--------- test/packet_injector_test_frame.cpp | 122 +++---- test/packet_injector_test_frame.h | 12 +- .../raw/fw.pcap | Bin 0 -> 6956 bytes .../raw/virtio_dign_c.pcap | Bin 0 -> 896 bytes .../raw/virtio_dign_s.pcap | Bin 0 -> 356 bytes ...ct-192.0.2.110:80-192.0.2.212:54146-1.pcap | Bin 0 -> 138 bytes ...ct-192.0.2.110:80-192.0.2.212:54146-2.pcap | Bin 0 -> 101 bytes ...ct-192.0.2.110:80-192.0.2.212:54146-3.pcap | Bin 0 -> 94 bytes ...ct-192.0.2.212:54146-192.0.2.110:80-4.pcap | Bin 0 -> 94 bytes .../test/input.pcap | Bin 0 -> 2484 bytes 24 files changed, 580 insertions(+), 410 deletions(-) create mode 100644 test/gtest_inject_tcp_payload_after_recv_c2s_first_payload.cpp delete mode 100644 test/gtest_inject_tcp_rst.cpp create mode 100644 test/gtest_inject_tcp_rst_after_recv_c2s_first_payload.cpp create mode 100644 test/gtest_inject_tcp_rst_after_recv_s2c_first_payload.cpp create mode 100644 test/gtest_inject_tcp_rst_after_recv_sub_ack.cpp create mode 100644 test/gtest_inject_tcp_rst_after_recv_syn_ack.cpp create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/fw.pcap create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_c.pcap create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_s.pcap create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.212:54146-1.pcap create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.212:54146-2.pcap create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.212:54146-3.pcap create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.212:54146-192.0.2.110:80-4.pcap create mode 100644 test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/input.pcap diff --git a/src/packet/packet_priv.h b/src/packet/packet_priv.h index cfbafeb..dfcce46 100644 --- a/src/packet/packet_priv.h +++ b/src/packet/packet_priv.h @@ -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); int packet_is_fragment(const struct packet *pkt); +int packet_get_fingerprint(const struct packet *pkt, char *buff, int size); #ifdef __cplusplus } diff --git a/src/packet/packet_utils.cpp b/src/packet/packet_utils.cpp index 351253f..610d939 100644 --- a/src/packet/packet_utils.cpp +++ b/src/packet/packet_utils.cpp @@ -2,6 +2,10 @@ #include #include +#include "udp_utils.h" +#include "tcp_utils.h" +#include "ipv4_utils.h" +#include "ipv6_utils.h" #include "packet_priv.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"); } } + +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; +} \ No newline at end of file diff --git a/src/packet_io/dumpfile_io.cpp b/src/packet_io/dumpfile_io.cpp index 8c55ed1..0545ff7 100644 --- a/src/packet_io/dumpfile_io.cpp +++ b/src/packet_io/dumpfile_io.cpp @@ -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); fflush(fp); fclose(fp); - PACKET_IO_LOG_DEBUG("save packet to %s", file); + PACKET_IO_LOG_STATE("save packet to %s", file); } else { diff --git a/src/stellar/config.cpp b/src/stellar/config.cpp index a291a67..23dbe43 100644 --- a/src/stellar/config.cpp +++ b/src/stellar/config.cpp @@ -491,7 +491,7 @@ void stellar_print_config(struct stellar_config *config) CONFIG_LOG_DEBUG("packet_io->nr_threads : %d", io_opts->nr_threads); 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 diff --git a/src/stellar/inject.cpp b/src/stellar/inject.cpp index e34bec2..a163ceb 100644 --- a/src/stellar/inject.cpp +++ b/src/stellar/inject.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -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] - 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->ttl = (uint8_t)(RANGE(random, 48, 120)); finger->win = (uint16_t)(RANGE(random, 1000, 1460)); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6b9299d..11bbc2b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,8 +1,28 @@ -add_executable(gtest_inject_tcp_rst packet_injector.cpp gtest_inject_tcp_rst.cpp packet_injector_test_frame.cpp ) -target_link_libraries(gtest_inject_tcp_rst core gtest) +add_library(libpacket_injector packet_injector.cpp packet_injector_test_frame.cpp) +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) -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) target_link_libraries(packet_injector core gtest) diff --git a/test/README.md b/test/README.md index 736eb10..c12fbb9 100644 --- a/test/README.md +++ b/test/README.md @@ -39,4 +39,5 @@ curl -v http://http.badssl.selftest.gdnt-cloud.website --resolve "http.badssl.se | tcp-rst | s2c-packet | 1 | After recv SYN-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 | s2c-packet | 3 | After recv S2C First-payload | Success | \ No newline at end of file +| tcp-rst | s2c-packet | 3 | After recv S2C First-payload | Success | +| tcp-payload | c2s-packet | 3 | After recv C2S First-Payload | Success | \ No newline at end of file diff --git a/test/gtest_inject_tcp_payload_after_recv_c2s_first_payload.cpp b/test/gtest_inject_tcp_payload_after_recv_c2s_first_payload.cpp new file mode 100644 index 0000000..c69ebc5 --- /dev/null +++ b/test/gtest_inject_tcp_payload_after_recv_c2s_first_payload.cpp @@ -0,0 +1,62 @@ +#include + +#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(); +} diff --git a/test/gtest_inject_tcp_rst.cpp b/test/gtest_inject_tcp_rst.cpp deleted file mode 100644 index 371af21..0000000 --- a/test/gtest_inject_tcp_rst.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include - -#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(); -} diff --git a/test/gtest_inject_tcp_rst_after_recv_c2s_first_payload.cpp b/test/gtest_inject_tcp_rst_after_recv_c2s_first_payload.cpp new file mode 100644 index 0000000..0850fcc --- /dev/null +++ b/test/gtest_inject_tcp_rst_after_recv_c2s_first_payload.cpp @@ -0,0 +1,54 @@ +#include + +#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(); +} diff --git a/test/gtest_inject_tcp_rst_after_recv_s2c_first_payload.cpp b/test/gtest_inject_tcp_rst_after_recv_s2c_first_payload.cpp new file mode 100644 index 0000000..52d611a --- /dev/null +++ b/test/gtest_inject_tcp_rst_after_recv_s2c_first_payload.cpp @@ -0,0 +1,54 @@ +#include + +#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(); +} diff --git a/test/gtest_inject_tcp_rst_after_recv_sub_ack.cpp b/test/gtest_inject_tcp_rst_after_recv_sub_ack.cpp new file mode 100644 index 0000000..141b765 --- /dev/null +++ b/test/gtest_inject_tcp_rst_after_recv_sub_ack.cpp @@ -0,0 +1,54 @@ +#include + +#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(); +} diff --git a/test/gtest_inject_tcp_rst_after_recv_syn_ack.cpp b/test/gtest_inject_tcp_rst_after_recv_syn_ack.cpp new file mode 100644 index 0000000..1edc319 --- /dev/null +++ b/test/gtest_inject_tcp_rst_after_recv_syn_ack.cpp @@ -0,0 +1,54 @@ +#include + +#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(); +} diff --git a/test/packet_injector.cpp b/test/packet_injector.cpp index 91c2e4b..c2b5383 100644 --- a/test/packet_injector.cpp +++ b/test/packet_injector.cpp @@ -17,10 +17,8 @@ #include "stellar/tuple.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 @@ -50,157 +48,7 @@ struct inject_rule uint64_t count_num; } rule; -static void inject_packet_plugin(struct session *sess, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env) -{ - 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; -} +#define INJECT_PACKET_PLUGIN_LOG_DEBUG(format, ...) LOG_DEBUG("inject packet plugin", format, ##__VA_ARGS__) static void usage(char *cmd) { @@ -219,7 +67,7 @@ static void usage(char *cmd) 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)); @@ -342,9 +190,155 @@ static int parse_cmdline(int argc, char **argv, struct inject_rule *rule) 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; } @@ -400,12 +394,12 @@ int inject_packet_main(int argc, char **argv) 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); 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, udp_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, packet_injector_on_msg, sess_plug_id); if (stellar_thread_init(runtime, config) != 0) { @@ -452,5 +446,5 @@ error_out: int __attribute__((weak)) main(int argc, char **argv) { - return inject_packet_main(argc, argv); + return packet_injector_main(argc, argv); } \ No newline at end of file diff --git a/test/packet_injector_test_frame.cpp b/test/packet_injector_test_frame.cpp index 758168b..da5e493 100644 --- a/test/packet_injector_test_frame.cpp +++ b/test/packet_injector_test_frame.cpp @@ -78,58 +78,44 @@ static int replace_file_string(const char *file, const char *old_str, const char return 0; } -static void expect_cmp_inject(const char *work_dir, - 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) +static void expect_cmp_inject(const char *expect_pcap_file, const char *inject_pcap_file, const char *diff_skip_pattern, int idx) { struct stat s; - char expect_pcap_file_abs_path[1024] = {0}; - char output_pcap_file_abs_path[1024] = {0}; - char expect_json_file_abs_path[1024] = {0}; - char output_json_file_abs_path[1024] = {0}; - char diff_txt_file_abs_path[1024] = {0}; + char expect_pcap_json[1024] = {0}; + char inject_pcap_json[1024] = {0}; + char diff_json_txt[1024] = {0}; - // absulute path - snprintf(expect_pcap_file_abs_path, sizeof(expect_pcap_file_abs_path), "%s/%s", expect_dir_abs_path, expect_pcap_file); - snprintf(output_pcap_file_abs_path, sizeof(output_pcap_file_abs_path), "%s/%s", output_dir_abs_path, output_pcap_file); - 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); + snprintf(expect_pcap_json, sizeof(expect_pcap_json), "expect_pcap_%d.json", idx); + snprintf(inject_pcap_json, sizeof(inject_pcap_json), "inject_pcap_%d.json", idx); + snprintf(diff_json_txt, sizeof(diff_json_txt), "json_diff_%d.txt", idx); - // check pcap file size - stat(expect_pcap_file_abs_path, &s); + stat(expect_pcap_file, &s); EXPECT_TRUE(s.st_size > 0); - stat(output_pcap_file_abs_path, &s); + stat(inject_pcap_file, &s); EXPECT_TRUE(s.st_size > 0); - // tcpdump - 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_abs_path); + printf("\033[32m tcpdump read expect pcap (%s) \033[0m\n", expect_pcap_file); + system_cmd("tcpdump -r %s", expect_pcap_file); - printf("\033[32m tcpdump read [%s] output pcap (%s) \033[0m\n", flow_dir, output_pcap_file); - system_cmd("tcpdump -r %s", output_pcap_file_abs_path); + printf("\033[32m tcpdump read inject pcap (%s) \033[0m\n", inject_pcap_file); + system_cmd("tcpdump -r %s", inject_pcap_file); - // tshark - 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", output_pcap_file_abs_path, output_json_file_abs_path); + system_cmd("tshark -r %s -T json | jq >> %s", expect_pcap_file, expect_pcap_json); + system_cmd("tshark -r %s -T json | jq >> %s", inject_pcap_file, inject_pcap_json); - // check json file size - stat(expect_json_file_abs_path, &s); + stat(expect_pcap_json, &s); EXPECT_TRUE(s.st_size > 0); - stat(output_json_file_abs_path, &s); + stat(inject_pcap_json, &s); EXPECT_TRUE(s.st_size > 0); - // diff - 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); + system_cmd("diff %s %s %s >> %s", diff_skip_pattern, expect_pcap_json, inject_pcap_json, diff_json_txt); - // check diff file size - stat(diff_txt_file_abs_path, &s); + stat(diff_json_txt, &s); 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) { @@ -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[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 + 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("mkdir -p %s", input_dir_abs_path); - system_cmd("mkdir -p %s", output_dir_abs_path); - system_cmd("mkdir -p %s", expect_dir_abs_path); - system_cmd("mkdir -p %s", log_dir_abs_path); + system_cmd("mkdir -p %s", dumpfile_dir); + system_cmd("mkdir -p %s/log/", test->work_dir); // 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) + { + system_cmd("cp %s/%s %s", test->input_prefix, test->compares[i].expect_pcap, test->work_dir); + } } - 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->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 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 - char cwd[1024]; + char cwd[2048] = {0}; + char temp[2048] = {0}; getcwd(cwd, sizeof(cwd)); 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 - 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); - expect_cmp_inject(test->work_dir, - expect_dir_abs_path, test->c2s_expect_pcap, - 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"); + if (test->compares[i].expect_pcap && test->compares[i].inject_pcap) + { + expect_cmp_inject(test->compares[i].expect_pcap, test->compares[i].inject_pcap, test->diff_skip_pattern, i + 1); + } } // clean work directory diff --git a/test/packet_injector_test_frame.h b/test/packet_injector_test_frame.h index a04dd90..6b0b67b 100644 --- a/test/packet_injector_test_frame.h +++ b/test/packet_injector_test_frame.h @@ -6,6 +6,8 @@ extern "C" { #endif +#define MAX_COMPARISON 16 + struct packet_injector_case { // descriptor @@ -20,11 +22,11 @@ struct packet_injector_case const char *input_pcap; // compare - const char *c2s_expect_pcap; - const char *c2s_output_pcap; - - const char *s2c_expect_pcap; - const char *s2c_output_pcap; + struct + { + const char *expect_pcap; + const char *inject_pcap; + } compares[MAX_COMPARISON]; // packet injector command const char *packet_injector_cmd[16]; diff --git a/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/fw.pcap b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/fw.pcap new file mode 100644 index 0000000000000000000000000000000000000000..61103e3a7b02d3b4e939b20c3af4b0c23fa4f5fe GIT binary patch literal 6956 zcmeI0Z)h8J7{`BUv)aZ*ySk;?GCUB)ZcTERT>kW^w9{@@S2bw0j!r_7`=vQ{y&QL! z{t?AGs1Dg1r!RzUFsu@(ny=@LS|5ZHdNgElEl-vXp@^KL#7xHpGDo1@2 z(QrJ>6XGP>$*87^xlxrF<9sZ9m7pK=Q97fo2`o)75K;$MRMEp}R#9}$oKlW!0Io4kJeJ~XAfhTB5ds}` z7~A8Q_{bA!LYBqW6~)+0UnL**&sy{qEckk<^^KvXKJ>MNjEQv2J0@v{l#Se zN6Am=jJAr{_=3N;JqHJVIB)OI49?;&3fIe?6+YLIn~0K*v+?w}$>G_S;MEJq;2&_{ z{0118;Y-`#ypa8-HR%5It%uaG~k-9k; z%EhB3)-l`mCQK%0>VE%CYlJ&Gw|(HOYjm{@-SrUK9rg7tjKc{7@8?7#c@BnyoFK+T zC!=OHBQ7Z;8r5|nSo}=x`G$tHdP{KV=en2H0pqFu+Io02_`3F|NHtmqbRE zbVC>pvg|X=@G1l5M~NtD=#Qr3vZNd-dN;I0IxVHjrf?_}44IQuN;PwmgB&*Rr6tCh z3{8kaq?0ick}QNfnN&heq$Fb!ZK<3VhnNHobOR3|iMn7L6aF8jPnhA~HC7mo%HC!Ypw&zx!b^VrV^mUR97?v?|n?MhuQF}Kk*zjbxZZ4q6c zxO`jH82>9>Zy@7p>v}UXFX?&#V3hJTcVTD#e%NbqROD-({}y#UHH(@?Z5Q+P3~2k% zR5R)E3`4ean7R5<)HSHwlBbcm0i%|u1-9CG8kypr{fmX|%pdE|7MYgvbAfFwKW}tR zhK!MQ9~8tT9WVNK<}0^7E#S`)qZ5JL&oH-Q_xdaQ`6VXZi;RV}8!Zxn2EP zsAQRpVW_@jLezEHr&Bp?P~Gs2h>GD&$=RIf8>dNKGN{}2Bs44DeIrm`3s`u{{)jIe z_OWi)zEp~;VBF*1<94~BtgqNF7Qj~9FRH&^;M&18)M!~l(YI%_B&RrgXz*b=ounpD67e0S>IO1D)@Ae8so~GQ9Z_`9^P8_ zb^q$ghk*r-3dZ*q88a&wA2%8AbS{o}!`IBc+sZZrwi;WzcQn;wTdMo4Y}>Ccv8|{D ztZXZ4`WUjEzb>|Gy>Ht>do%2t|Ka`H#+wV-aXKmOXH`#t(V+$*16TCA= GwtoY=*N8d* literal 0 HcmV?d00001 diff --git a/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_c.pcap b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_c.pcap new file mode 100644 index 0000000000000000000000000000000000000000..963ac3a2637c70d254d2f261c6f788a3dc5ed37c GIT binary patch literal 896 zcmca|c+)~A1{MYcU}0bca;|y#q)mLr#^42HgRt7pvwY9x*IjGe@H>@*!Igo*#^j0v zg9BT`(gO@kSAaP0auY*<<{GI*Ad?m_{rXVE!N9=8!n%cpiGxcjT-g&O&dAKn1u}Wp zAB4#eGa=?fOlDvJnY^_UWGcvXhJedW#xY3|K+_j55c=2g(hXtqU0ESFkm)d!Zvahp z0@?(^7;ZK(xe9jk8jz_V)1hu&3^YBmL4d(tEE?!WMzDMRKqiCS`W|TFN}y>VjA7zz zlWSlTU9g%c!C?PvEvkv`t|1Eg3LYUL0s4k|hP+%J`Nbtx3K=CO1$s$|DaFM(dc~8W`@P06K2Ir`>$W@dT@yj+gS z$*BcEK`nhPUM^m6AZPt$V@Luz8iX+dIb>t51A_${_ZLtwfE*7EJL@5XLY}18SH8nqfU)!$epfl-odZMK^v=-T-@YB^FQifIWE-)sq15-3!qG literal 0 HcmV?d00001 diff --git a/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_s.pcap b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_s.pcap new file mode 100644 index 0000000000000000000000000000000000000000..76b091b36e7e50a86fc4fa8a88cecd858b255a3b GIT binary patch literal 356 zcmca|c+)~A1{MYcU}0bca;|y#r0M)&WAFm9L0E0)S-$7;>#j9!_?^nZ;L5;YV{*lT z!GWz|=>Z0&D?prgxrre_bB)v@kVy-eetjt7U|?WkVco*Q#K9#MuIvdCXJlsP0+}3u zWHQ7|i1`qc85lq&Z>%!xI?UwXK$D$- zHi0mPn@vovg5A6ZWGcvXsGAo9O^<94V6Yd92D*_E>|Q^R$so5@|7Bw^1DXcH7$$0L W%ynR}VB=B1W@3N{%Y*W33=9CHqh-wi literal 0 HcmV?d00001 diff --git a/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.212:54146-1.pcap b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.212:54146-1.pcap new file mode 100644 index 0000000000000000000000000000000000000000..abcaf5ad964fdec667d267dc3d3008b803cc5507 GIT binary patch literal 138 zcmca|c+)~A1{MYcU}0bca;|y#q-FhOV@LwBL3rJ@#tpwy)pnlcdoItx;L5-dvN6|z z!GewZ%K-+aJRrWp5OBH4I3_7lbB#1tfB?&bQ?d*U9w8wC`i6Rj3PuJ73jW@_T+aD< cC8>EOx<09S=_MIf3Wi3!T)bQ!sX00M0MvFRuK)l5 literal 0 HcmV?d00001 diff --git a/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.212:54146-2.pcap b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.212:54146-2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9c0f65547e2d04585d8a4bef4353c3d4a317f2e5 GIT binary patch literal 101 zcmca|c+)~A1{MYw`2U}Qff2}AJjE;RN;)TlEszbu>#j9!_?@b@^DN(Uc@73w1_u3y t{0@~ literal 0 HcmV?d00001 diff --git a/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.212:54146-192.0.2.110:80-4.pcap b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/expect-192.0.2.212:54146-192.0.2.110:80-4.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ae2cd2ea3e06878d5672ac8c493c890fa16813c8 GIT binary patch literal 94 zcmca|c+)~A1{MYcU}0bca;|y#q*ecAV=x1#j9!_?^nZ;L5 literal 0 HcmV?d00001 diff --git a/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/input.pcap b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/input.pcap new file mode 100644 index 0000000000000000000000000000000000000000..391886471accbd360f3ee33a5787d9b66eee29a7 GIT binary patch literal 2484 zcmeH|&1(}u6u@8Fw6?+cQT(DHE(n5}Y<8PX8kd5pw0@z|Lq(;^ve}(&2e+GLXVQ;b z_2k*Bm!kF{sCdwWC;bBy6sso%52ASUtf0QPO=>l%CqacSyu6v0H*em|Z{AEQolcDa zz{!FAy$RIc>R&tb!U-PKW|V@e_p5p#tE+tsjj#zqhi5hXOrv6I+ER?h*oJNyLk~i|bqq2u&tJwi z7~-2J-1dd54Z2s9#r~Z_lS6-8_zMl06TfZuqe4 z?yF1pzOXJB1{g3F%TVr|TX+m@izva1%P_L{cJFm`hWWP7pQ0|Lmh8BnZ0kz(p4okj z?1}dF6tPUA(0oZUVs2MK&SaFZ8cB->;}H|W%-8#@-tEgMTv(X06ERydQ_Com%oeqX zO|n2*ayDdUDfV$>Un}mvc!8#4S|#JYG84fdK0#o!2OTRe4kM= z`m|y{@=3sc5ZqOKE~Gh@*R%`D*lz^=OW^W|;xW(id2q2FT}HO&ac9|7EEMvE*ePTz zik%X0KAtPGrK&@!aDgxGT(-Inn=^?sC$! z&&2ju#+7G13k}9gbeBjkF$O3j;|H_E7iAGfUR=(fubf5BH|Bf3UioJ)JsQ#hXu=kTO&&wkw3M3g&x~38{{|fy_F7wdShRtRlE%>C|a_ sz_NqmcpsZ|QTe%kwOCZObZXFXSct}bxqazW8lQl*GxV3<06IJ00h(@w!~g&Q literal 0 HcmV?d00001