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 0000000..61103e3 Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/fw.pcap differ 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 0000000..963ac3a Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_c.pcap differ 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 0000000..76b091b Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/raw/virtio_dign_s.pcap differ 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 0000000..abcaf5a Binary files /dev/null and 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 differ 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 0000000..9c0f655 Binary files /dev/null and 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 differ 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-3.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-3.pcap new file mode 100644 index 0000000..d6f089f Binary files /dev/null and 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-3.pcap differ 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 0000000..ae2cd2e Binary files /dev/null and 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 differ 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 0000000..3918864 Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_after_recv_c2s_first_payload/test/input.pcap differ