feature: packet IO support IP reassembly
This commit is contained in:
@@ -1,4 +1,49 @@
|
||||
#include "gtest_utils.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packet_parser.h"
|
||||
#include "packet_helper.h"
|
||||
#include "packet_internal.h"
|
||||
#include "ip_reassembly.h"
|
||||
|
||||
static inline void packet_overwrite_v4_saddr(struct packet *pkt, uint32_t saddr)
|
||||
{
|
||||
const struct layer_private *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_PROTO_IPV4);
|
||||
EXPECT_TRUE(ipv4_layer);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
ip4_hdr_set_src_addr(hdr, saddr);
|
||||
}
|
||||
|
||||
static inline void stat_cmp(struct ip_reassembly_stat *curr, struct ip_reassembly_stat *expect)
|
||||
{
|
||||
EXPECT_TRUE(curr != NULL);
|
||||
EXPECT_TRUE(expect != NULL);
|
||||
|
||||
EXPECT_TRUE(curr->ip4_defrags_expected == expect->ip4_defrags_expected);
|
||||
EXPECT_TRUE(curr->ip4_defrags_succeed == expect->ip4_defrags_succeed);
|
||||
EXPECT_TRUE(curr->ip4_defrags_failed == expect->ip4_defrags_failed);
|
||||
|
||||
EXPECT_TRUE(curr->ip4_frags == expect->ip4_frags);
|
||||
EXPECT_TRUE(curr->ip4_frags_freed == expect->ip4_frags_freed);
|
||||
EXPECT_TRUE(curr->ip4_frags_buffered == expect->ip4_frags_buffered);
|
||||
EXPECT_TRUE(curr->ip4_frags_no_buffer == expect->ip4_frags_no_buffer);
|
||||
EXPECT_TRUE(curr->ip4_frags_timeout == expect->ip4_frags_timeout);
|
||||
EXPECT_TRUE(curr->ip4_frags_invalid_length == expect->ip4_frags_invalid_length);
|
||||
EXPECT_TRUE(curr->ip4_frags_overlap == expect->ip4_frags_overlap);
|
||||
EXPECT_TRUE(curr->ip4_frags_too_many == expect->ip4_frags_too_many);
|
||||
|
||||
EXPECT_TRUE(curr->ip6_defrags_expected == expect->ip6_defrags_expected);
|
||||
EXPECT_TRUE(curr->ip6_defrags_succeed == expect->ip6_defrags_succeed);
|
||||
EXPECT_TRUE(curr->ip6_defrags_failed == expect->ip6_defrags_failed);
|
||||
|
||||
EXPECT_TRUE(curr->ip6_frags == expect->ip6_frags);
|
||||
EXPECT_TRUE(curr->ip6_frags_freed == expect->ip6_frags_freed);
|
||||
EXPECT_TRUE(curr->ip6_frags_buffered == expect->ip6_frags_buffered);
|
||||
EXPECT_TRUE(curr->ip6_frags_no_buffer == expect->ip6_frags_no_buffer);
|
||||
EXPECT_TRUE(curr->ip6_frags_timeout == expect->ip6_frags_timeout);
|
||||
EXPECT_TRUE(curr->ip6_frags_invalid_length == expect->ip6_frags_invalid_length);
|
||||
EXPECT_TRUE(curr->ip6_frags_overlap == expect->ip6_frags_overlap);
|
||||
EXPECT_TRUE(curr->ip6_frags_too_many == expect->ip6_frags_too_many);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frame 4: 60 bytes on wire (480 bits), 60 bytes captured (480 bits)
|
||||
@@ -194,60 +239,58 @@ unsigned char expect[] = {
|
||||
#if 1
|
||||
TEST(IPV4_REASSEMBLE, PADDING_ORDER)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
struct packet frag_pkt1 = {};
|
||||
struct packet frag_pkt2 = {};
|
||||
struct packet *frag_pkt = NULL;
|
||||
struct packet *defrag_pkt = NULL;
|
||||
const struct layer_private *layer;
|
||||
struct ip_reassembly *assy;
|
||||
struct ip_reassembly_config cfg = {
|
||||
.enable = true,
|
||||
.bucket_entries = 16,
|
||||
.bucket_num = 8,
|
||||
.ip_frag_timeout_ms = 1,
|
||||
.ip_frag_expire_polling_interval_ms = 0,
|
||||
.ip_frag_expire_polling_limit = 1024,
|
||||
struct ip_reassembly *ip_reass;
|
||||
struct ip_reassembly_stat *curr_stat;
|
||||
struct ip_reassembly_stat expect_stat;
|
||||
|
||||
ip_reass = ip_reassembly_new(1, 1024, 64);
|
||||
EXPECT_TRUE(ip_reass != NULL);
|
||||
curr_stat = ip_reassembly_get_stat(ip_reass);
|
||||
EXPECT_TRUE(curr_stat != NULL);
|
||||
expect_stat = {
|
||||
0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
|
||||
assy = ip_reassembly_new(&cfg, 0);
|
||||
EXPECT_TRUE(assy != NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag1
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt1, (const char *)frag1, sizeof(frag1));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt1, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
1, 0, 1, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag2
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
2, 2, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt2, (const char *)frag2, sizeof(frag2));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt2, 1);
|
||||
EXPECT_TRUE(defrag_pkt);
|
||||
expect_stat = {
|
||||
1, 1, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 2, 2, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// check packet
|
||||
packet_print(new_pkt);
|
||||
EXPECT_TRUE(new_pkt->data_len == 14 /* ETH */ + 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(new_pkt->data_len == sizeof(expect));
|
||||
EXPECT_TRUE(memcmp(new_pkt->data_ptr, expect, new_pkt->data_len) == 0);
|
||||
EXPECT_TRUE(defrag_pkt->data_len == 14 /* ETH */ + 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(defrag_pkt->data_len == sizeof(expect));
|
||||
EXPECT_TRUE(memcmp(defrag_pkt->data_ptr, expect, defrag_pkt->data_len) == 0);
|
||||
|
||||
// check IPv4
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_IPV4);
|
||||
layer = packet_get_innermost_layer(defrag_pkt, LAYER_PROTO_IPV4);
|
||||
EXPECT_TRUE(layer);
|
||||
struct ip *hdr = (struct ip *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
|
||||
@@ -266,7 +309,7 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
|
||||
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
|
||||
|
||||
// check TCP
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_TCP);
|
||||
layer = packet_get_innermost_layer(defrag_pkt, LAYER_PROTO_TCP);
|
||||
EXPECT_TRUE(layer);
|
||||
struct tcphdr *tcp_hdr = (struct tcphdr *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(tcp_hdr_get_src_port(tcp_hdr) == 62629);
|
||||
@@ -282,69 +325,89 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
|
||||
EXPECT_TRUE(tcp_hdr_get_opt_data(tcp_hdr) == NULL);
|
||||
|
||||
// free packet
|
||||
packet_free(new_pkt);
|
||||
EXPECT_TRUE(packet_is_defraged(defrag_pkt));
|
||||
|
||||
ip_reassembly_free(assy);
|
||||
frag_pkt = packet_pop_frag(defrag_pkt);
|
||||
EXPECT_TRUE(frag_pkt);
|
||||
packet_free(frag_pkt);
|
||||
|
||||
frag_pkt = packet_pop_frag(defrag_pkt);
|
||||
EXPECT_TRUE(frag_pkt);
|
||||
packet_free(frag_pkt);
|
||||
|
||||
frag_pkt = packet_pop_frag(defrag_pkt);
|
||||
EXPECT_TRUE(frag_pkt == NULL);
|
||||
|
||||
packet_free(defrag_pkt);
|
||||
|
||||
EXPECT_TRUE(ip_reassembly_clean(ip_reass, 2) == NULL);
|
||||
expect_stat = {
|
||||
1, 1, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 2, 2, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
ip_reassembly_free(ip_reass);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
struct packet frag_pkt1 = {};
|
||||
struct packet frag_pkt2 = {};
|
||||
struct packet *frag_pkt = NULL;
|
||||
struct packet *defrag_pkt = NULL;
|
||||
const struct layer_private *layer;
|
||||
struct ip_reassembly *assy;
|
||||
struct ip_reassembly_config cfg = {
|
||||
.enable = true,
|
||||
.bucket_entries = 16,
|
||||
.bucket_num = 8,
|
||||
.ip_frag_timeout_ms = 1,
|
||||
.ip_frag_expire_polling_interval_ms = 0,
|
||||
.ip_frag_expire_polling_limit = 1024,
|
||||
struct ip_reassembly *ip_reass;
|
||||
struct ip_reassembly_stat *curr_stat;
|
||||
struct ip_reassembly_stat expect_stat;
|
||||
|
||||
ip_reass = ip_reassembly_new(1, 1024, 64);
|
||||
EXPECT_TRUE(ip_reass != NULL);
|
||||
curr_stat = ip_reassembly_get_stat(ip_reass);
|
||||
EXPECT_TRUE(curr_stat != NULL);
|
||||
expect_stat = {
|
||||
0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
|
||||
assy = ip_reassembly_new(&cfg, 0);
|
||||
EXPECT_TRUE(assy != NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag2
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt2, (const char *)frag2, sizeof(frag2));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt2, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
1, 0, 1, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag1
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
2, 2, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt1, (const char *)frag1, sizeof(frag1));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt1, 1);
|
||||
EXPECT_TRUE(defrag_pkt);
|
||||
expect_stat = {
|
||||
1, 1, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 2, 2, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// check packet
|
||||
packet_print(new_pkt);
|
||||
EXPECT_TRUE(new_pkt->data_len == 14 /* ETH */ + 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(new_pkt->data_len == sizeof(expect));
|
||||
EXPECT_TRUE(memcmp(new_pkt->data_ptr, expect, new_pkt->data_len) == 0);
|
||||
EXPECT_TRUE(defrag_pkt->data_len == 14 /* ETH */ + 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(defrag_pkt->data_len == sizeof(expect));
|
||||
EXPECT_TRUE(memcmp(defrag_pkt->data_ptr, expect, defrag_pkt->data_len) == 0);
|
||||
|
||||
// check IPv4
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_IPV4);
|
||||
layer = packet_get_innermost_layer(defrag_pkt, LAYER_PROTO_IPV4);
|
||||
EXPECT_TRUE(layer);
|
||||
struct ip *hdr = (struct ip *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
|
||||
@@ -363,7 +426,7 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
|
||||
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
|
||||
|
||||
// check TCP
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_TCP);
|
||||
layer = packet_get_innermost_layer(defrag_pkt, LAYER_PROTO_TCP);
|
||||
EXPECT_TRUE(layer);
|
||||
struct tcphdr *tcp_hdr = (struct tcphdr *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(tcp_hdr_get_src_port(tcp_hdr) == 62629);
|
||||
@@ -379,358 +442,308 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
|
||||
EXPECT_TRUE(tcp_hdr_get_opt_data(tcp_hdr) == NULL);
|
||||
|
||||
// free packet
|
||||
packet_free(new_pkt);
|
||||
EXPECT_TRUE(packet_is_defraged(defrag_pkt));
|
||||
|
||||
ip_reassembly_free(assy);
|
||||
frag_pkt = packet_pop_frag(defrag_pkt);
|
||||
EXPECT_TRUE(frag_pkt);
|
||||
packet_free(frag_pkt);
|
||||
|
||||
frag_pkt = packet_pop_frag(defrag_pkt);
|
||||
EXPECT_TRUE(frag_pkt);
|
||||
packet_free(frag_pkt);
|
||||
|
||||
frag_pkt = packet_pop_frag(defrag_pkt);
|
||||
EXPECT_TRUE(frag_pkt == NULL);
|
||||
|
||||
packet_free(defrag_pkt);
|
||||
|
||||
EXPECT_TRUE(ip_reassembly_clean(ip_reass, 2) == NULL);
|
||||
expect_stat = {
|
||||
1, 1, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 2, 2, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
ip_reassembly_free(ip_reass);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(IPV4_REASSEMBLE, EXPIRE)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
struct ip_reassembly *assy;
|
||||
struct ip_reassembly_config cfg = {
|
||||
.enable = true,
|
||||
.bucket_entries = 16,
|
||||
.bucket_num = 8,
|
||||
.ip_frag_timeout_ms = 1,
|
||||
.ip_frag_expire_polling_interval_ms = 0,
|
||||
.ip_frag_expire_polling_limit = 1024,
|
||||
struct packet frag_pkt1 = {};
|
||||
struct packet *defrag_pkt = NULL;
|
||||
struct ip_reassembly *ip_reass;
|
||||
struct ip_reassembly_stat *curr_stat;
|
||||
struct ip_reassembly_stat expect_stat;
|
||||
|
||||
ip_reass = ip_reassembly_new(1, 1024, 64);
|
||||
EXPECT_TRUE(ip_reass != NULL);
|
||||
curr_stat = ip_reassembly_get_stat(ip_reass);
|
||||
EXPECT_TRUE(curr_stat != NULL);
|
||||
expect_stat = {
|
||||
0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
|
||||
assy = ip_reassembly_new(&cfg, 0);
|
||||
EXPECT_TRUE(assy != NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag1
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
packet_parse(&frag_pkt1, (const char *)frag1, sizeof(frag1));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt1, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
1, 0, 1, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
struct packet *pkt = NULL;
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
expect_stat = {
|
||||
1, 0, 1, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
1, 1, 1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag2
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 2);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
2, 0, 1, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
2, 1, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
|
||||
// free packet
|
||||
packet_free(new_pkt);
|
||||
|
||||
ip_reassembly_free(assy);
|
||||
ip_reassembly_free(ip_reass);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_private *layer;
|
||||
struct ip_reassembly *assy;
|
||||
struct ip_reassembly_config cfg = {
|
||||
.enable = true,
|
||||
.bucket_entries = 16,
|
||||
.bucket_num = 8,
|
||||
.ip_frag_timeout_ms = 1,
|
||||
.ip_frag_expire_polling_interval_ms = 0,
|
||||
.ip_frag_expire_polling_limit = 1024,
|
||||
struct packet frag_pkt1 = {};
|
||||
struct packet frag_pkt2 = {};
|
||||
struct packet *defrag_pkt = NULL;
|
||||
struct ip_reassembly *ip_reass;
|
||||
struct ip_reassembly_stat *curr_stat;
|
||||
struct ip_reassembly_stat expect_stat;
|
||||
|
||||
ip_reass = ip_reassembly_new(1, 1024, 64);
|
||||
EXPECT_TRUE(ip_reass != NULL);
|
||||
curr_stat = ip_reassembly_get_stat(ip_reass);
|
||||
EXPECT_TRUE(curr_stat != NULL);
|
||||
expect_stat = {
|
||||
0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
|
||||
assy = ip_reassembly_new(&cfg, 0);
|
||||
EXPECT_TRUE(assy != NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag1
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt1, (const char *)frag1, sizeof(frag1));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt1, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
1, 0, 1, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag1
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
packet_parse(&frag_pkt2, (const char *)frag1, sizeof(frag1));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt2, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 1, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 1, 1, 0, 0, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
2, 0, 1, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
struct packet *pkt = NULL;
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 1, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 1, 1, 0, 0, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag2
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
3, 2, 2, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
|
||||
// check packet
|
||||
packet_print(new_pkt);
|
||||
EXPECT_TRUE(new_pkt->data_len == 14 /* ETH */ + 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(new_pkt->data_len == sizeof(expect));
|
||||
EXPECT_TRUE(memcmp(new_pkt->data_ptr, expect, new_pkt->data_len) == 0);
|
||||
|
||||
// check IPv4
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_IPV4);
|
||||
EXPECT_TRUE(layer);
|
||||
struct ip *hdr = (struct ip *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
|
||||
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
|
||||
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
|
||||
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 0xffff);
|
||||
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 0x0);
|
||||
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
|
||||
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
|
||||
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
|
||||
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
|
||||
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
|
||||
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
|
||||
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
|
||||
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
|
||||
|
||||
// check TCP
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_TCP);
|
||||
EXPECT_TRUE(layer);
|
||||
struct tcphdr *tcp_hdr = (struct tcphdr *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(tcp_hdr_get_src_port(tcp_hdr) == 62629);
|
||||
EXPECT_TRUE(tcp_hdr_get_dst_port(tcp_hdr) == 9999);
|
||||
EXPECT_TRUE(tcp_hdr_get_seq(tcp_hdr) == 2433164423);
|
||||
EXPECT_TRUE(tcp_hdr_get_ack(tcp_hdr) == 64297191);
|
||||
EXPECT_TRUE(tcp_hdr_get_hdr_len(tcp_hdr) == 20);
|
||||
EXPECT_TRUE(tcp_hdr_get_flags(tcp_hdr) == 0x018);
|
||||
EXPECT_TRUE(tcp_hdr_get_window(tcp_hdr) == 65280);
|
||||
EXPECT_TRUE(tcp_hdr_get_checksum(tcp_hdr) == 0x5e92);
|
||||
EXPECT_TRUE(tcp_hdr_get_urg_ptr(tcp_hdr) == 0);
|
||||
EXPECT_TRUE(tcp_hdr_get_opt_len(tcp_hdr) == 0);
|
||||
EXPECT_TRUE(tcp_hdr_get_opt_data(tcp_hdr) == NULL);
|
||||
|
||||
// free packet
|
||||
packet_free(new_pkt);
|
||||
|
||||
ip_reassembly_free(assy);
|
||||
ip_reassembly_free(ip_reass);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_private *layer;
|
||||
struct ip_reassembly *assy;
|
||||
struct ip_reassembly_config cfg = {
|
||||
.enable = true,
|
||||
.bucket_entries = 16,
|
||||
.bucket_num = 8,
|
||||
.ip_frag_timeout_ms = 1,
|
||||
.ip_frag_expire_polling_interval_ms = 0,
|
||||
.ip_frag_expire_polling_limit = 1024,
|
||||
struct packet frag_pkt1 = {};
|
||||
struct packet frag_pkt2 = {};
|
||||
struct packet *defrag_pkt = NULL;
|
||||
struct ip_reassembly *ip_reass;
|
||||
struct ip_reassembly_stat *curr_stat;
|
||||
struct ip_reassembly_stat expect_stat;
|
||||
|
||||
ip_reass = ip_reassembly_new(1, 1024, 64);
|
||||
EXPECT_TRUE(ip_reass != NULL);
|
||||
curr_stat = ip_reassembly_get_stat(ip_reass);
|
||||
EXPECT_TRUE(curr_stat != NULL);
|
||||
expect_stat = {
|
||||
0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
|
||||
assy = ip_reassembly_new(&cfg, 0);
|
||||
EXPECT_TRUE(assy != NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag2
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt1, (const char *)frag2, sizeof(frag2));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt1, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
1, 0, 1, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag2
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
packet_parse(&frag_pkt2, (const char *)frag2, sizeof(frag2));
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt2, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 1, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 1, 1, 0, 0, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
2, 0, 1, 0, 0, 1, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
struct packet *pkt = NULL;
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 1, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 1, 1, 0, 0, 0, 1, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// frag1
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 1, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
3, 2, 2, 0, 0, 1, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
|
||||
// check packet
|
||||
packet_print(new_pkt);
|
||||
EXPECT_TRUE(new_pkt->data_len == 14 /* ETH */ + 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(new_pkt->data_len == sizeof(expect));
|
||||
EXPECT_TRUE(memcmp(new_pkt->data_ptr, expect, new_pkt->data_len) == 0);
|
||||
|
||||
// check IPv4
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_IPV4);
|
||||
EXPECT_TRUE(layer);
|
||||
struct ip *hdr = (struct ip *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(ip4_hdr_get_version(hdr) == 4);
|
||||
EXPECT_TRUE(ip4_hdr_get_hdr_len(hdr) == 20 /* IPv4 */);
|
||||
EXPECT_TRUE(ip4_hdr_get_tos(hdr) == 0);
|
||||
EXPECT_TRUE(ip4_hdr_get_total_len(hdr) == 20 /* IPv4 */ + 20 /* TCP */ + 28 /* DATA */);
|
||||
EXPECT_TRUE(ip4_hdr_get_ipid(hdr) == 0xffff);
|
||||
EXPECT_TRUE(ip4_hdr_get_flags(hdr) == 0x0);
|
||||
EXPECT_TRUE(ip4_hdr_get_frag_offset(hdr) == 0);
|
||||
EXPECT_TRUE(ip4_hdr_get_ttl(hdr) == 127);
|
||||
EXPECT_TRUE(ip4_hdr_get_proto(hdr) == 6);
|
||||
EXPECT_TRUE(ip4_hdr_get_checksum(hdr) == 0x6d73); // NOTE this is correct checksum
|
||||
EXPECT_TRUE(ip4_hdr_get_src_addr(hdr) == 0xc0a82467);
|
||||
EXPECT_TRUE(ip4_hdr_get_dst_addr(hdr) == 0xc0a82889);
|
||||
EXPECT_TRUE(ip4_hdr_get_opt_len(hdr) == 0);
|
||||
EXPECT_TRUE(ip4_hdr_get_opt_data(hdr) == NULL);
|
||||
|
||||
// check TCP
|
||||
layer = packet_get_innermost_layer(new_pkt, LAYER_PROTO_TCP);
|
||||
EXPECT_TRUE(layer);
|
||||
struct tcphdr *tcp_hdr = (struct tcphdr *)layer->hdr_ptr;
|
||||
EXPECT_TRUE(tcp_hdr_get_src_port(tcp_hdr) == 62629);
|
||||
EXPECT_TRUE(tcp_hdr_get_dst_port(tcp_hdr) == 9999);
|
||||
EXPECT_TRUE(tcp_hdr_get_seq(tcp_hdr) == 2433164423);
|
||||
EXPECT_TRUE(tcp_hdr_get_ack(tcp_hdr) == 64297191);
|
||||
EXPECT_TRUE(tcp_hdr_get_hdr_len(tcp_hdr) == 20);
|
||||
EXPECT_TRUE(tcp_hdr_get_flags(tcp_hdr) == 0x018);
|
||||
EXPECT_TRUE(tcp_hdr_get_window(tcp_hdr) == 65280);
|
||||
EXPECT_TRUE(tcp_hdr_get_checksum(tcp_hdr) == 0x5e92);
|
||||
EXPECT_TRUE(tcp_hdr_get_urg_ptr(tcp_hdr) == 0);
|
||||
EXPECT_TRUE(tcp_hdr_get_opt_len(tcp_hdr) == 0);
|
||||
EXPECT_TRUE(tcp_hdr_get_opt_data(tcp_hdr) == NULL);
|
||||
|
||||
// free packet
|
||||
packet_free(new_pkt);
|
||||
|
||||
ip_reassembly_free(assy);
|
||||
ip_reassembly_free(ip_reass);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(IPV4_REASSEMBLE, FULL)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
struct ip_reassembly *assy;
|
||||
struct ip_reassembly_config cfg = {
|
||||
.enable = true,
|
||||
.bucket_entries = 1,
|
||||
.bucket_num = 1,
|
||||
.ip_frag_timeout_ms = 1,
|
||||
.ip_frag_expire_polling_interval_ms = 0,
|
||||
.ip_frag_expire_polling_limit = 1024,
|
||||
struct packet frag_pkt1 = {};
|
||||
struct packet frag_pkt2 = {};
|
||||
struct packet frag_pkt3 = {};
|
||||
struct packet *defrag_pkt = NULL;
|
||||
struct ip_reassembly *ip_reass;
|
||||
struct ip_reassembly_stat *curr_stat;
|
||||
struct ip_reassembly_stat expect_stat;
|
||||
|
||||
ip_reass = ip_reassembly_new(1, 2, 64);
|
||||
EXPECT_TRUE(ip_reass != NULL);
|
||||
curr_stat = ip_reassembly_get_stat(ip_reass);
|
||||
EXPECT_TRUE(curr_stat != NULL);
|
||||
expect_stat = {
|
||||
0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
assy = ip_reassembly_new(&cfg, 0);
|
||||
EXPECT_TRUE(assy != NULL);
|
||||
char dup1[sizeof(frag1)] = {0};
|
||||
char dup2[sizeof(frag1)] = {0};
|
||||
char dup3[sizeof(frag1)] = {0};
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
0, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
|
||||
char dup_frag[sizeof(frag1)] = {0};
|
||||
memcpy(dup_frag, frag1, sizeof(frag1));
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
packet_parse(&pkt, (const char *)dup_frag, sizeof(dup_frag));
|
||||
memcpy(dup1, frag1, sizeof(frag1));
|
||||
memcpy(dup2, frag1, sizeof(frag1));
|
||||
memcpy(dup3, frag1, sizeof(frag1));
|
||||
|
||||
// flow1
|
||||
packet_set_ipv4_src_addr(&pkt, 1);
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
1, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
1, 0, 1, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt1, (const char *)dup1, sizeof(dup1));
|
||||
packet_overwrite_v4_saddr(&frag_pkt1, 1);
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt1, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
1, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
1, 0, 1, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// flow2
|
||||
packet_set_ipv4_src_addr(&pkt, 2);
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
2, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
2, 0, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
packet_parse(&frag_pkt2, (const char *)dup2, sizeof(dup2));
|
||||
packet_overwrite_v4_saddr(&frag_pkt2, 2);
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt2, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
2, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
2, 0, 2, 0, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// flow3
|
||||
packet_set_ipv4_src_addr(&pkt, 3);
|
||||
new_pkt = ip_reassembly_packet(assy, &pkt, 1);
|
||||
EXPECT_TRUE(new_pkt == NULL);
|
||||
packet_parse(&frag_pkt3, (const char *)dup3, sizeof(dup3));
|
||||
packet_overwrite_v4_saddr(&frag_pkt3, 3);
|
||||
defrag_pkt = ip_reassembly_defrag(ip_reass, &frag_pkt3, 1);
|
||||
EXPECT_TRUE(defrag_pkt == NULL);
|
||||
expect_stat = {
|
||||
2, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
3, 0, 2, 1, 0, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
check_stat(ip_reassembly_stat(assy),
|
||||
2, 0, 0, 0, 0, 0, // ip4: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
3, 0, 2, 1, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
0, 0, 0, 0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed_timeout, defrags_failed_invalid_length, defrags_failed_overlap, defrags_failed_too_many_frag
|
||||
0, 0, 0, 0, 0, 0); // ip6: frags, frags_freed, frags_buffered, frags_bypass_no_buffer, frags_bypass_dup_fist_frag, frags_bypass_dup_last_frag
|
||||
struct packet *pkt = NULL;
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt);
|
||||
packet_free(pkt);
|
||||
pkt = ip_reassembly_clean(ip_reass, 2);
|
||||
EXPECT_TRUE(pkt == NULL);
|
||||
expect_stat = {
|
||||
2, 0, 2, // ip4: defrags_expected, defrags_succeed, defrags_failed
|
||||
3, 2, 2, 1, 2, 0, 0, 0, // ip4: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
0, 0, 0, // ip6: defrags_expected, defrags_succeed, defrags_failed
|
||||
0, 0, 0, 0, 0, 0, 0, 0 // ip6: frags, frags_freed, frags_buffered, frags_no_buffer, timeout, invalid_length, overlap, too_many
|
||||
};
|
||||
stat_cmp(curr_stat, &expect_stat);
|
||||
|
||||
// free packet
|
||||
packet_free(new_pkt);
|
||||
|
||||
ip_reassembly_free(assy);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(IPV4_REASSEMBLE, OVERLAP)
|
||||
{
|
||||
// TEST ON IPv6
|
||||
ip_reassembly_free(ip_reass);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user