diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:39:49 +0000 |
commit | a0aa2307322cd47bbf416810ac0292925e03be87 (patch) | |
tree | 37076262a026c4b48c8a0e84f44ff9187556ca35 /src/stream-tcp-util.c | |
parent | Initial commit. (diff) | |
download | suricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip |
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/stream-tcp-util.c')
-rw-r--r-- | src/stream-tcp-util.c | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/src/stream-tcp-util.c b/src/stream-tcp-util.c new file mode 100644 index 0000000..4d8bf8a --- /dev/null +++ b/src/stream-tcp-util.c @@ -0,0 +1,253 @@ +/* Copyright (C) 2007-2011 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. + */ + +/** + * \file + * + * \author Victor Julien <victor@inliniac.net> + * + * Helper functions for the stream engine. + */ + +#include "suricata-common.h" + +#include "stream-tcp-reassemble.h" +#include "stream-tcp-inline.h" +#include "stream-tcp.h" +#include "stream-tcp-util.h" + +#include "util-memcmp.h" +#include "util-print.h" + +#include "util-unittest.h" +#include "util-unittest-helper.h" +#include "ippair.h" + +#ifdef UNITTESTS + +/* unittest helper functions */ + +void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx) +{ + StreamTcpInitConfig(true); + IPPairInitConfig(true); + *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); +} + +void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx) +{ + StreamTcpReassembleFreeThreadCtx(ra_ctx); + StreamTcpFreeConfig(true); + stream_config.flags &= ~STREAMTCP_INIT_FLAG_INLINE; +} + +void StreamTcpUTInitInline(void) { + stream_config.flags |= STREAMTCP_INIT_FLAG_INLINE; +} + +void StreamTcpUTSetupSession(TcpSession *ssn) +{ + memset(ssn, 0x00, sizeof(TcpSession)); + + StreamingBuffer x = STREAMING_BUFFER_INITIALIZER; + ssn->client.sb = x; + ssn->server.sb = x; +} + +void StreamTcpUTClearSession(TcpSession *ssn) +{ + StreamTcpUTClearStream(&ssn->client); + StreamTcpUTClearStream(&ssn->server); + StreamTcpSessionCleanup(ssn); + memset(ssn, 0x00, sizeof(TcpSession)); +} + +void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn) +{ + memset(s, 0x00, sizeof(TcpStream)); + + s->isn = isn; + STREAMTCP_SET_RA_BASE_SEQ(s, isn); + s->base_seq = isn+1; + + StreamingBuffer x = STREAMING_BUFFER_INITIALIZER; + s->sb = x; +} + +void StreamTcpUTClearStream(TcpStream *s) +{ + StreamTcpStreamCleanup(s); +} + +/** \brief wrapper for StreamTcpReassembleHandleSegmentHandleData */ +int StreamTcpUTAddPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len) +{ + Packet *p = UTHBuildPacketReal(payload, len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); + if (p == NULL) { + return -1; + } + p->tcph->th_seq = htonl(seq); + p->tcph->th_ack = htonl(31); + + if (StreamTcpReassembleHandleSegmentHandleData(tv, ra_ctx, ssn, stream, p) < 0) + return -1; + + UTHFreePacket(p); + return 0; +} + +int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len) +{ + TcpSegment *s = StreamTcpGetSegment(tv, ra_ctx); + if (s == NULL) { + return -1; + } + + s->seq = seq; + TCP_SEG_LEN(s) = len; + + Packet *p = UTHBuildPacketReal(payload, len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); + if (p == NULL) { + return -1; + } + p->tcph->th_seq = htonl(seq); + + if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_SEQ(p), p->payload, p->payload_len) < 0) + return -1; + + UTHFreePacket(p); + return 0; +} + +int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len) +{ + TcpSegment *s = StreamTcpGetSegment(tv, ra_ctx); + if (s == NULL) { + return -1; + } + + s->seq = seq; + TCP_SEG_LEN(s) = len; + uint8_t buf[len]; + memset(buf, byte, len); + + Packet *p = UTHBuildPacketReal(buf, len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); + if (p == NULL) { + return -1; + } + p->tcph->th_seq = htonl(seq); + + if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_SEQ(p), p->payload, p->payload_len) < 0) + return -1; + UTHFreePacket(p); + return 0; +} + +/* tests */ + +static int StreamTcpUtilTest01(void) +{ + int ret = 0; + TcpReassemblyThreadCtx *ra_ctx = NULL; + + StreamTcpUTInit(&ra_ctx); + + if (ra_ctx == NULL) { + printf("ra_ctx is NULL: "); + goto end; + } + + ret = 1; +end: + StreamTcpUTDeinit(ra_ctx); + return ret; +} + + +static int StreamTcpUtilStreamTest01(void) +{ + TcpReassemblyThreadCtx *ra_ctx = NULL; + TcpStream stream; + ThreadVars tv; + memset(&tv, 0x00, sizeof(tv)); + + StreamTcpUTInit(&ra_ctx); + StreamTcpUTSetupStream(&stream, 1); + + FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1); + FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1); + FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1); + + TcpSegment *seg = RB_MIN(TCPSEG, &stream.seg_tree); + FAIL_IF_NULL(seg); + FAIL_IF(seg->seq != 2); + + seg = TCPSEG_RB_NEXT(seg); + FAIL_IF_NULL(seg); + FAIL_IF(seg->seq != 7); + + seg = TCPSEG_RB_NEXT(seg); + FAIL_IF_NULL(seg); + FAIL_IF(seg->seq != 12); + + StreamTcpUTClearStream(&stream); + StreamTcpUTDeinit(ra_ctx); + PASS; +} + +static int StreamTcpUtilStreamTest02(void) +{ + TcpReassemblyThreadCtx *ra_ctx = NULL; + TcpStream stream; + ThreadVars tv; + memset(&tv, 0x00, sizeof(tv)); + + StreamTcpUTInit(&ra_ctx); + StreamTcpUTSetupStream(&stream, 1); + + FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1); + FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1); + FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1); + + TcpSegment *seg = RB_MIN(TCPSEG, &stream.seg_tree); + FAIL_IF_NULL(seg); + FAIL_IF(seg->seq != 2); + + seg = TCPSEG_RB_NEXT(seg); + FAIL_IF_NULL(seg); + FAIL_IF(seg->seq != 7); + + seg = TCPSEG_RB_NEXT(seg); + FAIL_IF_NULL(seg); + FAIL_IF(seg->seq != 12); + + StreamTcpUTClearStream(&stream); + StreamTcpUTDeinit(ra_ctx); + PASS; +} + +#endif + +void StreamTcpUtilRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("StreamTcpUtilTest01", StreamTcpUtilTest01); + UtRegisterTest("StreamTcpUtilStreamTest01", StreamTcpUtilStreamTest01); + UtRegisterTest("StreamTcpUtilStreamTest02", StreamTcpUtilStreamTest02); +#endif /* UNITTESTS */ +} + |