Add packet injector test frame
This commit is contained in:
@@ -1,15 +1,11 @@
|
||||
add_executable(gtest_build_tcp_packet gtest_build_tcp_packet.cpp)
|
||||
target_link_libraries(gtest_build_tcp_packet core gtest)
|
||||
|
||||
add_executable(gtest_build_udp_packet gtest_build_udp_packet.cpp)
|
||||
target_link_libraries(gtest_build_udp_packet core gtest)
|
||||
add_executable(gtest_inject_tcp_rst gtest_inject_tcp_rst.cpp packet_injector_test_frame.cpp)
|
||||
target_link_libraries(gtest_inject_tcp_rst core gtest)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(gtest_build_tcp_packet)
|
||||
gtest_discover_tests(gtest_build_udp_packet)
|
||||
gtest_discover_tests(gtest_inject_tcp_rst)
|
||||
|
||||
add_executable(packet_injector packet_injector.cpp)
|
||||
target_link_libraries(packet_injector core gtest)
|
||||
|
||||
file(COPY ./conf/log.toml DESTINATION ./conf/)
|
||||
file(COPY ./conf/stellar.toml DESTINATION ./conf/)
|
||||
file(COPY ./conf/ DESTINATION ./conf/)
|
||||
file(COPY ./pcap/ DESTINATION ./pcap/)
|
||||
@@ -29,4 +29,12 @@ tcpdump -i virtio_dign_s host 192.0.2.110 and port 80 -n -v -w virtio_dign_s.pca
|
||||
``` shell
|
||||
kubectl -n tsg-os-system exec -it dign-client-9h8rm -c dign-client sh
|
||||
curl -v http://http.badssl.selftest.gdnt-cloud.website --resolve "http.badssl.selftest.gdnt-cloud.website:80:192.0.2.110"
|
||||
```
|
||||
```
|
||||
|
||||
## 结果
|
||||
|
||||
| -t | -c | -n | Note | result |
|
||||
| ----------- | ----------- | ----------- | ---------------------------- | ----------- |
|
||||
| tcp-rst | c2s-packet | 1 | After recv SYN | Failed |
|
||||
| tcp-rst | s2c-packet | 1 | After recv SYN-ACK | Success |
|
||||
| tcp-rst | c2s-packet | 2 | After recv Sub-ACK | Success |
|
||||
@@ -1,63 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "inject_priv.h"
|
||||
|
||||
/******************************************************************************
|
||||
* BUILD_TCP_PACKET
|
||||
******************************************************************************/
|
||||
|
||||
// IPv4
|
||||
TEST(BUILD_IPV4_BASED_TCP_PACKET, WITH_RST)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
TEST(BUILD_IPV4_BASED_TCP_PACKET, WITH_FIN)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
TEST(BUILD_IPV4_BASED_TCP_PACKET, WITH_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// IPv6
|
||||
TEST(BUILD_IPV6_BASED_TCP_PACKET, WITH_RST)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
TEST(BUILD_IPV6_BASED_TCP_PACKET, WITH_FIN)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
TEST(BUILD_IPV6_BASED_TCP_PACKET, WITH_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// IPv4 + IPv6
|
||||
TEST(BUILD_IPV4_IPV6_BASED_TCP_PACKET, WITH_RST)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// IPv6 + IPv4
|
||||
TEST(BUILD_IPV6_IPV4_BASED_TCP_PACKET, WITH_RST)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// GRE
|
||||
TEST(BUILD_GRE_BASED_TCP_PACKET, WITH_RST)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "inject_priv.h"
|
||||
|
||||
/******************************************************************************
|
||||
* BUILD_UDP_PACKET
|
||||
******************************************************************************/
|
||||
|
||||
// IPv4
|
||||
TEST(BUILD_IPV4_BASED_UDP_PACKET, NO_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
TEST(BUILD_IPV4_BASED_UDP_PACKET, WITH_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// IPv6
|
||||
TEST(BUILD_IPV6_BASED_UDP_PACKET, NO_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
TEST(BUILD_IPV6_BASED_UDP_PACKET, WITH_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// IPv4 + IPv6
|
||||
TEST(BUILD_IPV4_IPV6_BASED_UDP_PACKET, WITH_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// IPv6 + IPv4
|
||||
TEST(BUILD_IPV6_IPV4_BASED_UDP_PACKET, WITH_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// GRE
|
||||
TEST(BUILD_GRE_BASED_UDP_PACKET, WITH_PAYLOD)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
39
test/gtest_inject_tcp_rst.cpp
Normal file
39
test/gtest_inject_tcp_rst.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packet_injector_test_frame.h"
|
||||
|
||||
TEST(INJECT_IPV4_BASED_TCP_RST, AFTER_RECV_SYN_ACK)
|
||||
{
|
||||
struct packet_injector_case test = {
|
||||
// descriptor
|
||||
.finish_clean_work_dir = 1,
|
||||
.descriptor = "Inject IPv4 based TCP RST after receiving SYN-ACK packet.",
|
||||
.work_dir = "/tmp/inject_ipv4_based_tcp_rst_after_recv_syn_ack/", // user defined work directory
|
||||
|
||||
// prefix
|
||||
.input_prefix = "pcap/inject_ipv4_based_tcp_rst_after_recv_syn_ack/test/",
|
||||
.output_prefix = "/tmp/",
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -339,12 +339,12 @@ static int parse_cmdline(int argc, char **argv, struct inject_rule *rule)
|
||||
printf("invalid count\n");
|
||||
return -1;
|
||||
}
|
||||
printf("load inject rule:\n");
|
||||
printf(" host : %s\n", host);
|
||||
printf(" port : %d\n", ntohs(rule->port));
|
||||
printf(" type : %s\n", type);
|
||||
printf(" condition : %s\n", condition);
|
||||
printf(" count : %lu\n\n", rule->count_num);
|
||||
printf("%s load inject rule:\n", argv[0]);
|
||||
printf(" host : %s\n", host);
|
||||
printf(" port : %d\n", ntohs(rule->port));
|
||||
printf(" type : %s\n", type);
|
||||
printf(" condition : %s\n", condition);
|
||||
printf(" count : %lu\n\n", rule->count_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -368,7 +368,6 @@ int main(int argc, char **argv)
|
||||
STELLAR_LOG_ERROR("unable to init log");
|
||||
goto error_out;
|
||||
}
|
||||
STELLAR_LOG_STATE("start stellar (version: %s)\n %s", __stellar_version, logo_str);
|
||||
|
||||
if (stellar_load_config(stellar_config_file, config) != 0)
|
||||
{
|
||||
@@ -427,6 +426,11 @@ int main(int argc, char **argv)
|
||||
stellar_stat_output(runtime->stat);
|
||||
}
|
||||
usleep(1000); // 1ms
|
||||
|
||||
if (packet_io_wait_exit(runtime->packet_io))
|
||||
{
|
||||
ATOMIC_SET(&runtime->need_exit, 1);
|
||||
}
|
||||
}
|
||||
|
||||
error_out:
|
||||
|
||||
205
test/packet_injector_test_frame.cpp
Normal file
205
test/packet_injector_test_frame.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "packet_injector_test_frame.h"
|
||||
|
||||
static void system_cmd(const char *cmd, ...)
|
||||
{
|
||||
char buf[1024] = {0};
|
||||
va_list args;
|
||||
|
||||
va_start(args, cmd);
|
||||
vsnprintf(buf, sizeof(buf), cmd, args);
|
||||
va_end(args);
|
||||
|
||||
system(buf);
|
||||
}
|
||||
|
||||
static int replace_file_string(const char *file, const char *old_str, const char *new_str)
|
||||
{
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
FILE *in_fp = fopen(file, "r");
|
||||
if (in_fp == NULL)
|
||||
{
|
||||
printf("Open file %s failed, %s\n", file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *tmp_fp = tmpfile();
|
||||
if (tmp_fp == NULL)
|
||||
{
|
||||
printf("Create temporary file failed, %s\n", strerror(errno));
|
||||
fclose(in_fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t old_len = strlen(old_str);
|
||||
size_t new_len = strlen(new_str);
|
||||
char buff[BUFFER_SIZE];
|
||||
|
||||
while (fgets(buff, BUFFER_SIZE, in_fp))
|
||||
{
|
||||
char *pos = buff;
|
||||
if ((pos = strstr(pos, old_str)))
|
||||
{
|
||||
fwrite(buff, 1, pos - buff, tmp_fp); // Write characters before the old_str
|
||||
fwrite(new_str, 1, new_len, tmp_fp); // Write the new_str
|
||||
pos += old_len; // Move past the old_str
|
||||
fwrite(pos, 1, strlen(pos), tmp_fp); // Write characters after the old_str
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs(buff, tmp_fp); // Write the remaining part of the line
|
||||
}
|
||||
}
|
||||
|
||||
fclose(in_fp);
|
||||
fseek(tmp_fp, 0, SEEK_SET);
|
||||
|
||||
FILE *out_fp = fopen(file, "w");
|
||||
if (out_fp == NULL)
|
||||
{
|
||||
printf("Open file %s for writing failed, %s\n", file, strerror(errno));
|
||||
fclose(tmp_fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(buff, BUFFER_SIZE, tmp_fp))
|
||||
{
|
||||
fputs(buff, out_fp); // Write the contents of the temporary file to the original file
|
||||
}
|
||||
|
||||
fclose(tmp_fp);
|
||||
fclose(out_fp);
|
||||
|
||||
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)
|
||||
{
|
||||
printf("\033[32m ============================================= \033[0m\n");
|
||||
printf("\033[32m Compare [%s] expect pcap and output pcap \033[0m\n", flow_dir);
|
||||
printf("\033[32m ============================================= \033[0m\n");
|
||||
|
||||
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};
|
||||
|
||||
// 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);
|
||||
|
||||
// check pcap file size
|
||||
stat(expect_pcap_file_abs_path, &s);
|
||||
EXPECT_TRUE(s.st_size > 0);
|
||||
|
||||
stat(output_pcap_file_abs_path, &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 [%s] output pcap (%s) \033[0m\n", flow_dir, output_pcap_file);
|
||||
system_cmd("tcpdump -r %s", output_pcap_file_abs_path);
|
||||
|
||||
// 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);
|
||||
|
||||
// check json file size
|
||||
stat(expect_json_file_abs_path, &s);
|
||||
EXPECT_TRUE(s.st_size > 0);
|
||||
|
||||
stat(output_json_file_abs_path, &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);
|
||||
|
||||
// check diff file size
|
||||
stat(diff_txt_file_abs_path, &s);
|
||||
EXPECT_TRUE(s.st_size == 0);
|
||||
}
|
||||
|
||||
void packet_injector_test_frame_run(struct packet_injector_case *test)
|
||||
{
|
||||
printf("\033[32mTest: %s\033[0m\n", test->descriptor);
|
||||
|
||||
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};
|
||||
|
||||
// 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);
|
||||
|
||||
// create directory
|
||||
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);
|
||||
|
||||
// copy file to work directory
|
||||
if (test->c2s_expect_pcap)
|
||||
{
|
||||
system_cmd("cp %s/%s %s", test->input_prefix, test->c2s_expect_pcap, expect_dir_abs_path);
|
||||
}
|
||||
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 -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
|
||||
chdir(test->work_dir);
|
||||
system_cmd(test->packet_injector_cmd);
|
||||
chdir("../");
|
||||
|
||||
// compare pcap
|
||||
if (test->c2s_output_pcap && test->c2s_expect_pcap)
|
||||
{
|
||||
system_cmd("mv %s/%s %s", test->output_prefix, 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->output_prefix, test->s2c_output_pcap, output_dir_abs_path);
|
||||
expect_cmp_inject(test->work_dir,
|
||||
expect_dir_abs_path, test->s2c_expect_pcap,
|
||||
output_dir_abs_path, test->s2c_output_pcap,
|
||||
test->diff_skip_pattern, "S2C");
|
||||
}
|
||||
|
||||
// clean work directory
|
||||
if (test->finish_clean_work_dir)
|
||||
{
|
||||
system_cmd("rm -rf %s", test->work_dir);
|
||||
}
|
||||
}
|
||||
41
test/packet_injector_test_frame.h
Normal file
41
test/packet_injector_test_frame.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef _PACKET_INJECTOR_TEST_FRAME_H
|
||||
#define _PACKET_INJECTOR_TEST_FRAME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct packet_injector_case
|
||||
{
|
||||
// descriptor
|
||||
int finish_clean_work_dir;
|
||||
const char *descriptor;
|
||||
const char *work_dir;
|
||||
|
||||
// prefix
|
||||
const char *input_prefix;
|
||||
const char *output_prefix;
|
||||
|
||||
// input pcap
|
||||
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;
|
||||
|
||||
// packet injector command
|
||||
const char *packet_injector_cmd;
|
||||
const char *diff_skip_pattern;
|
||||
};
|
||||
|
||||
void packet_injector_test_frame_run(struct packet_injector_case *test);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test/pcap/inject_ipv4_based_tcp_rst_after_recv_syn/raw/fw.pcap
Normal file
BIN
test/pcap/inject_ipv4_based_tcp_rst_after_recv_syn/raw/fw.pcap
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user