diff --git a/src/stellar/inject.cpp b/src/stellar/inject.cpp index a163ceb..b04edd9 100644 --- a/src/stellar/inject.cpp +++ b/src/stellar/inject.cpp @@ -165,7 +165,7 @@ static void update_ip6_hdr(struct ip6_hdr *ip6hdr, int trim) ipv6_hdr_set_payload_len(ip6hdr, len - trim); } -static inline void calc_tcp_seq_ack(const struct session *sess, enum flow_direction inject_dir, uint32_t *seq, uint32_t *ack, uint16_t len) +static inline void calc_tcp_seq_ack(const struct session *sess, enum flow_direction inject_dir, uint32_t *seq, uint32_t *ack, uint8_t flags, uint16_t len) { /* * +--------+ current packet +---------+ C2S RST +--------+ @@ -196,6 +196,8 @@ static inline void calc_tcp_seq_ack(const struct session *sess, enum flow_direct *ack = tcp_curr_half->ack; tcp_curr_half->inject_inc_seq_offset += len; + // inject RST packer after FIN packer, seq should be increased by 1 + tcp_curr_half->inject_inc_seq_offset += (flags & TH_FIN) ? 1 : 0; } else { @@ -203,6 +205,8 @@ static inline void calc_tcp_seq_ack(const struct session *sess, enum flow_direct *ack = uint32_add(tcp_curr_half->seq, tcp_curr_half->len + (tcp_curr_half->flags & TH_SYN ? 1 : 0)); tcp_curr_half->inject_inc_ack_offset += len; + // inject RST packer after FIN packer, ack should be increased by 1 + tcp_curr_half->inject_inc_ack_offset += (flags & TH_FIN) ? 1 : 0; } } @@ -416,7 +420,7 @@ int inject_tcp_packet(const struct session *sess, enum flow_direction inject_dir uint32_t tcp_seq = 0; uint32_t tcp_ack = 0; char buff[4096] = {0}; - calc_tcp_seq_ack(sess, inject_dir, &tcp_seq, &tcp_ack, len); + calc_tcp_seq_ack(sess, inject_dir, &tcp_seq, &tcp_ack, tcp_flags, len); calc_tcp_fingerprint(&finger); int pkt_len = build_tcp_packet(pkt, finger.ipid, finger.ttl, tcp_seq, tcp_ack, tcp_flags, finger.win, payload, len, buff, sizeof(buff)); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ab62983..73afe23 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,6 +20,9 @@ target_link_libraries(gtest_inject_tcp_payload_after_recv_c2s_first_payload libp add_executable(gtest_inject_tcp_payload_after_recv_s2c_first_payload gtest_inject_tcp_payload_after_recv_s2c_first_payload.cpp) target_link_libraries(gtest_inject_tcp_payload_after_recv_s2c_first_payload libpacket_injector) +add_executable(gtest_inject_tcp_payload_fin_rst_after_recv_c2s_first_payload gtest_inject_tcp_payload_fin_rst_after_recv_c2s_first_payload.cpp) +target_link_libraries(gtest_inject_tcp_payload_fin_rst_after_recv_c2s_first_payload libpacket_injector) + include(GoogleTest) gtest_discover_tests(gtest_inject_tcp_rst_after_recv_syn_ack) gtest_discover_tests(gtest_inject_tcp_rst_after_recv_sub_ack) @@ -27,6 +30,7 @@ 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) gtest_discover_tests(gtest_inject_tcp_payload_after_recv_s2c_first_payload) +gtest_discover_tests(gtest_inject_tcp_payload_fin_rst_after_recv_c2s_first_payload) add_executable(packet_injector packet_injector.cpp) target_link_libraries(packet_injector core gtest) diff --git a/test/gtest_inject_tcp_payload_fin_rst_after_recv_c2s_first_payload.cpp b/test/gtest_inject_tcp_payload_fin_rst_after_recv_c2s_first_payload.cpp new file mode 100644 index 0000000..351d1cc --- /dev/null +++ b/test/gtest_inject_tcp_payload_fin_rst_after_recv_c2s_first_payload.cpp @@ -0,0 +1,70 @@ +#include + +#include "packet_injector_test_frame.h" + +TEST(INJECT_IPV4_BASED_TCP_PAYLOAD_FIN_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_payload_fin_rst_after_recv_c2s_first_payload"); + snprintf(input_dir, sizeof(input_dir), "%s/%s", current_dir, "pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/"); + + struct packet_injector_case test = { + // descriptor + .finish_clean_work_dir = 0, + .descriptor = "Inject IPv4 based TCP Payload & FIN & 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.110:80-192.0.2.213:37296-1.pcap", + .inject_pcap = "inject-192.0.2.110:80-192.0.2.213:37296-1.pcap", + }, + { + .expect_pcap = "expect-192.0.2.110:80-192.0.2.213:37296-2.pcap", + .inject_pcap = "inject-192.0.2.110:80-192.0.2.213:37296-2.pcap", + }, + { + .expect_pcap = "expect-192.0.2.110:80-192.0.2.213:37296-3.pcap", + .inject_pcap = "inject-192.0.2.110:80-192.0.2.213:37296-3.pcap", + }, + { + .expect_pcap = "expect-192.0.2.110:80-192.0.2.213:37296-4.pcap", + .inject_pcap = "inject-192.0.2.110:80-192.0.2.213:37296-4.pcap", + }, + { + .expect_pcap = "expect-192.0.2.213:37296-192.0.2.110:80-5.pcap", + .inject_pcap = "inject-192.0.2.213:37296-192.0.2.110:80-5.pcap", + }, + { + .expect_pcap = "expect-192.0.2.213:37296-192.0.2.110:80-6.pcap", + .inject_pcap = "inject-192.0.2.213:37296-192.0.2.110:80-6.pcap", + }, + { + .expect_pcap = NULL, + .inject_pcap = NULL, + }, + }, + + // packet injector command + .packet_injector_cmd = {"./packet_injector", "-t", "tcp-payload-fin-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/packet_injector.cpp b/test/packet_injector.cpp index c2b5383..46c7eb9 100644 --- a/test/packet_injector.cpp +++ b/test/packet_injector.cpp @@ -32,8 +32,9 @@ enum inject_type INJECT_TYPE_TCP_RST = 1, INJECT_TYPE_TCP_FIN = 2, INJECT_TYPE_TCP_PAYLOAD = 3, - INJECT_TYPE_UDP_PAYLOAD = 4, - INJECT_TYPE_CTRL_MSG = 5, + INJECT_TYPE_TCP_PAYLOAD_FIN_RST = 4, + INJECT_TYPE_UDP_PAYLOAD = 5, + INJECT_TYPE_CTRL_MSG = 6, }; struct inject_rule @@ -57,7 +58,7 @@ static void usage(char *cmd) printf(" -h Host IP address\n"); printf(" -p Port number\n"); printf(" -t Type of manipulation\n"); - printf(" Options: tcp-rst, tcp-fin, tcp-payload, udp-payload, ctrl-msg\n"); + printf(" Options: tcp-rst, tcp-fin, tcp-payload, tcp-payload-fin-rst, udp-payload, ctrl-msg\n"); printf(" -c Condition for manipulation\n"); printf(" Options: c2s-packet, s2c-packet\n"); printf(" -n Number of packets received before injecting action\n\n"); @@ -138,6 +139,10 @@ static int packet_injector_on_init(int argc, char **argv, struct inject_rule *ru { rule->inject_type = INJECT_TYPE_TCP_PAYLOAD; } + else if (strcmp(type, "tcp-payload-fin-rst") == 0) + { + rule->inject_type = INJECT_TYPE_TCP_PAYLOAD_FIN_RST; + } else if (strcmp(type, "udp-payload") == 0) { rule->inject_type = INJECT_TYPE_UDP_PAYLOAD; @@ -245,6 +250,16 @@ static void packet_injector_on_msg(struct session *sess, int topic_id, const voi EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_C2S) > 0); // inject RST to server session_set_discard(sess); break; + case INJECT_TYPE_TCP_PAYLOAD_FIN_RST: + 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_fin(sess, FLOW_DIRECTION_S2C) > 0); // inject FIN to client + EXPECT_TRUE(stellar_inject_tcp_rst(sess, FLOW_DIRECTION_S2C) > 0); // inject RST to client + EXPECT_TRUE(stellar_inject_tcp_fin(sess, FLOW_DIRECTION_C2S) > 0); // inject FIN to server + 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); diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/fw.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/fw.pcap new file mode 100644 index 0000000..fa2d84d Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/fw.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/virtio_dign_c.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/virtio_dign_c.pcap new file mode 100644 index 0000000..fca4cd4 Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/virtio_dign_c.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/virtio_dign_s.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/virtio_dign_s.pcap new file mode 100644 index 0000000..c7ee626 Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/raw/virtio_dign_s.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-1.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-1.pcap new file mode 100644 index 0000000..d6f1aa0 Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-1.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-2.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-2.pcap new file mode 100644 index 0000000..58a87f6 Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-2.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-3.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-3.pcap new file mode 100644 index 0000000..c02095a Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-3.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-4.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-4.pcap new file mode 100644 index 0000000..e4056ff Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.110:80-192.0.2.213:37296-4.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.213:37296-192.0.2.110:80-5.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.213:37296-192.0.2.110:80-5.pcap new file mode 100644 index 0000000..6eb7f4e Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.213:37296-192.0.2.110:80-5.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.213:37296-192.0.2.110:80-6.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.213:37296-192.0.2.110:80-6.pcap new file mode 100644 index 0000000..76b619d Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/expect-192.0.2.213:37296-192.0.2.110:80-6.pcap differ diff --git a/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/input.pcap b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/input.pcap new file mode 100644 index 0000000..4d26edd Binary files /dev/null and b/test/pcap/inject_ipv4_based_tcp_payload_fin_rst_after_recv_c2s_first_payload/test/input.pcap differ