summaryrefslogtreecommitdiffstats
path: root/src/tests/stream-tcp-reassemble.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/stream-tcp-reassemble.c')
-rw-r--r--src/tests/stream-tcp-reassemble.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/tests/stream-tcp-reassemble.c b/src/tests/stream-tcp-reassemble.c
new file mode 100644
index 0000000..5f07f33
--- /dev/null
+++ b/src/tests/stream-tcp-reassemble.c
@@ -0,0 +1,209 @@
+/* Copyright (C) 2007-2021 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "../suricata-common.h"
+#include "../stream-tcp-private.h"
+#include "../stream-tcp.h"
+#include "../stream-tcp-reassemble.h"
+#include "../stream-tcp-inline.h"
+#include "../stream-tcp-list.h"
+#include "../stream-tcp-util.h"
+#include "../util-streaming-buffer.h"
+#include "../util-print.h"
+#include "../util-unittest.h"
+
+struct TestReassembleRawCallbackData {
+ const uint8_t *expect_data;
+ const uint32_t expect_data_len;
+};
+
+static int TestReassembleRawCallback(
+ void *cb_data, const uint8_t *data, const uint32_t data_len, const uint64_t offset)
+{
+ struct TestReassembleRawCallbackData *cb = cb_data;
+
+ SCLogNotice("have %u expect %u", data_len, cb->expect_data_len);
+
+ if (data_len == cb->expect_data_len &&
+ memcmp(data, cb->expect_data, data_len) == 0) {
+ return 1;
+ } else {
+ SCLogNotice("data mismatch. Expected:");
+ PrintRawDataFp(stdout, cb->expect_data, cb->expect_data_len);
+ SCLogNotice("Got:");
+ PrintRawDataFp(stdout, data, data_len);
+ return -1;
+ }
+}
+
+static int TestReassembleRawValidate(TcpSession *ssn, Packet *p,
+ const uint8_t *data, const uint32_t data_len)
+{
+ struct TestReassembleRawCallbackData cb = { data, data_len };
+ uint64_t progress = 0;
+ int r = StreamReassembleRaw(ssn, p, TestReassembleRawCallback, &cb, &progress, false);
+ if (r == 1) {
+ StreamReassembleRawUpdateProgress(ssn, p, progress);
+ }
+ SCLogNotice("r %d", r);
+ return r;
+}
+
+#define RAWREASSEMBLY_START(isn) \
+ TcpReassemblyThreadCtx *ra_ctx = NULL; \
+ TcpSession ssn; \
+ ThreadVars tv; \
+ memset(&tv, 0, sizeof(tv)); \
+ Packet *p = NULL; \
+ \
+ \
+ StreamTcpUTInit(&ra_ctx); \
+ StreamTcpUTInitInline(); \
+ stream_config.reassembly_toserver_chunk_size = 9; \
+ stream_config.reassembly_toclient_chunk_size = 9; \
+ StreamTcpUTSetupSession(&ssn); \
+ StreamTcpUTSetupStream(&ssn.server, (isn)); \
+ StreamTcpUTSetupStream(&ssn.client, (isn)); \
+ ssn.server.last_ack = (isn) + 1; \
+ ssn.client.last_ack = (isn) + 1; \
+ \
+ TcpStream *stream = &ssn.client;
+
+#define RAWREASSEMBLY_END \
+ StreamTcpUTClearSession(&ssn); \
+ StreamTcpUTDeinit(ra_ctx); \
+ PASS
+
+#define RAWREASSEMBLY_STEP(seq, seg, seglen, buf, buflen) \
+ p = PacketGetFromAlloc(); \
+ FAIL_IF_NULL(p); \
+ { \
+ SCLogNotice("SEQ %u block of %u", (seq), (seglen)); \
+ p->flowflags = FLOW_PKT_TOSERVER; \
+ TCPHdr tcphdr; \
+ memset(&tcphdr, 0, sizeof(tcphdr)); \
+ p->tcph = &tcphdr; \
+ p->tcph->th_seq = htonl((seq)); \
+ p->tcph->th_ack = htonl(10); \
+ p->payload_len = (seglen); \
+ \
+ FAIL_IF(StreamTcpUTAddPayload(&tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen)) != 0); \
+ p->flags |= PKT_STREAM_ADD; \
+ FAIL_IF(!(TestReassembleRawValidate(&ssn, p, (uint8_t *)(buf), (buflen)))); \
+ }\
+ PacketFree(p);
+
+#define RAWREASSEMBLY_STEP_WITH_PROGRESS(seq, seg, seglen, buf, buflen, lastack, progress) \
+ stream->last_ack = (lastack); \
+ RAWREASSEMBLY_STEP((seq),(seg),(seglen),(buf),(buflen)); \
+ FAIL_IF(STREAM_RAW_PROGRESS(stream) != (progress));
+
+static int StreamTcpReassembleRawTest01 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP(2, "AAA", 3, "AAA", 3);
+ RAWREASSEMBLY_STEP(5, "BBB", 3, "AAABBB", 6);
+ RAWREASSEMBLY_STEP(8, "CCC", 3, "AAABBBCCC", 9);
+ RAWREASSEMBLY_END;
+}
+
+static int StreamTcpReassembleRawTest02 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP(2, "AAA", 3, "AAA", 3);
+ RAWREASSEMBLY_STEP(5, "BBB", 3, "AAABBB", 6);
+ RAWREASSEMBLY_STEP(11,"DDD", 3, "DDD", 3);
+ RAWREASSEMBLY_STEP(8, "CCC", 3, "BBBCCCDDD", 9);
+ RAWREASSEMBLY_END;
+}
+
+static int StreamTcpReassembleRawTest03 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP(2, "AAA", 3, "AAA", 3);
+ RAWREASSEMBLY_STEP(11,"DDD", 3, "DDD", 3);
+ RAWREASSEMBLY_STEP(8, "CCC", 3, "CCCDDD", 6);
+ RAWREASSEMBLY_END;
+}
+
+static int StreamTcpReassembleRawTest04 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP(2, "AAAAA", 5, "AAAAA", 5);
+ RAWREASSEMBLY_STEP(10,"CCCCC", 5, "CCCCC", 5);
+ RAWREASSEMBLY_STEP(7, "BBB", 3, "AAABBBCCC", 9);
+ RAWREASSEMBLY_END;
+}
+
+static int StreamTcpReassembleRawTest05 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP(2, "AAAAA", 5, "AAAAA", 5);
+ RAWREASSEMBLY_STEP(10,"CCCCC", 5, "CCCCC", 5);
+ RAWREASSEMBLY_STEP(2, "EEEEEEEEEEEEE", 13, "AAAAAEEECCCCC", 13);
+ RAWREASSEMBLY_END;
+}
+
+static int StreamTcpReassembleRawTest06 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP(2, "AAAAA", 5, "AAAAA", 5);
+ RAWREASSEMBLY_STEP(16,"CCCCC", 5, "CCCCC", 5);
+ RAWREASSEMBLY_STEP(7, "BBBBBBBBB", 9, "ABBBBBBBBBC", 11);
+ RAWREASSEMBLY_STEP(21,"DDDDDDDDDD",10,"CCCDDDDDDDDDD", 13);
+ RAWREASSEMBLY_END;
+}
+
+static int StreamTcpReassembleRawTest07 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP(2, "AAAAAAA", 7, "AAAAAAA", 7);
+ RAWREASSEMBLY_STEP(9, "BBBBBBB", 7, "AAABBBBBBB", 10);
+ RAWREASSEMBLY_STEP(16,"C", 1, "ABBBBBBBC", 9);
+ RAWREASSEMBLY_STEP(17,"DDDDDDDD",8,"BBCDDDDDDDD", 11);
+ RAWREASSEMBLY_END;
+}
+
+static int StreamTcpReassembleRawTest08 (void)
+{
+ RAWREASSEMBLY_START(1);
+ RAWREASSEMBLY_STEP_WITH_PROGRESS(2, "AAA", 3, "AAA", 3, 3, 3);
+ RAWREASSEMBLY_STEP_WITH_PROGRESS(8, "CCC", 3, "CCC", 3, 3, 3);
+ // segment lost, last_ack updated
+ RAWREASSEMBLY_STEP_WITH_PROGRESS(11, "DDD", 3, "CCCDDD", 6, 8, 12);
+ RAWREASSEMBLY_END;
+}
+
+static void StreamTcpReassembleRawRegisterTests(void)
+{
+ UtRegisterTest("StreamTcpReassembleRawTest01",
+ StreamTcpReassembleRawTest01);
+ UtRegisterTest("StreamTcpReassembleRawTest02",
+ StreamTcpReassembleRawTest02);
+ UtRegisterTest("StreamTcpReassembleRawTest03",
+ StreamTcpReassembleRawTest03);
+ UtRegisterTest("StreamTcpReassembleRawTest04",
+ StreamTcpReassembleRawTest04);
+ UtRegisterTest("StreamTcpReassembleRawTest05",
+ StreamTcpReassembleRawTest05);
+ UtRegisterTest("StreamTcpReassembleRawTest06",
+ StreamTcpReassembleRawTest06);
+ UtRegisterTest("StreamTcpReassembleRawTest07",
+ StreamTcpReassembleRawTest07);
+ UtRegisterTest("StreamTcpReassembleRawTest08",
+ StreamTcpReassembleRawTest08);
+}