diff options
Diffstat (limited to 'src/tests/stream-tcp-reassemble.c')
-rw-r--r-- | src/tests/stream-tcp-reassemble.c | 209 |
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); +} |