suricata
stream-tcp-util.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2011 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 *
23 * Helper functions for the stream engine.
24 */
25
26#include "suricata-common.h"
27
29#include "stream-tcp-inline.h"
30#include "stream-tcp.h"
31#include "stream-tcp-util.h"
32
33#include "util-memcmp.h"
34#include "util-print.h"
35
36#include "util-unittest.h"
38#include "ippair.h"
39
40#ifdef UNITTESTS
41
42/* unittest helper functions */
43
50
52{
55 stream_config.flags &= ~STREAMTCP_INIT_FLAG_INLINE;
56}
57
61
63{
64 memset(ssn, 0x00, sizeof(TcpSession));
65
67 ssn->client.sb = x;
68 ssn->server.sb = x;
69}
70
72{
76 memset(ssn, 0x00, sizeof(TcpSession));
77}
78
79void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn)
80{
81 memset(s, 0x00, sizeof(TcpStream));
82
83 s->isn = isn;
85 s->base_seq = isn+1;
86
88 s->sb = x;
89}
90
95
96/** \brief wrapper for StreamTcpReassembleHandleSegmentHandleData */
97int StreamTcpUTAddPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
98{
99 Packet *p = UTHBuildPacketReal(payload, len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
100 if (p == NULL) {
101 return -1;
102 }
103 p->l4.hdrs.tcph->th_seq = htonl(seq);
104 p->l4.hdrs.tcph->th_ack = htonl(31);
105
106 if (StreamTcpReassembleHandleSegmentHandleData(tv, ra_ctx, ssn, stream, p) < 0)
107 return -1;
108
109 UTHFreePacket(p);
110 return 0;
111}
112
113int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
114{
115 TcpSegment *s = StreamTcpGetSegment(tv, ra_ctx);
116 if (s == NULL) {
117 return -1;
118 }
119
120 s->seq = seq;
121 TCP_SEG_LEN(s) = len;
122
123 Packet *p = UTHBuildPacketReal(payload, len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
124 if (p == NULL) {
125 return -1;
126 }
127 p->l4.hdrs.tcph->th_seq = htonl(seq);
128
129 if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, p->payload, p->payload_len) < 0)
130 return -1;
131
132 UTHFreePacket(p);
133 return 0;
134}
135
136int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len)
137{
138 TcpSegment *s = StreamTcpGetSegment(tv, ra_ctx);
139 if (s == NULL) {
140 return -1;
141 }
142
143 s->seq = seq;
144 TCP_SEG_LEN(s) = len;
145 uint8_t buf[len];
146 memset(buf, byte, len);
147
148 Packet *p = UTHBuildPacketReal(buf, len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
149 if (p == NULL) {
150 return -1;
151 }
152 p->l4.hdrs.tcph->th_seq = htonl(seq);
153
154 if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, p->payload, p->payload_len) < 0)
155 return -1;
156 UTHFreePacket(p);
157 return 0;
158}
159
160/* tests */
161
162static int StreamTcpUtilTest01(void)
163{
164 int ret = 0;
165 TcpReassemblyThreadCtx *ra_ctx = NULL;
166
167 StreamTcpUTInit(&ra_ctx);
168
169 if (ra_ctx == NULL) {
170 printf("ra_ctx is NULL: ");
171 goto end;
172 }
173
174 ret = 1;
175end:
176 StreamTcpUTDeinit(ra_ctx);
177 return ret;
178}
179
180
181static int StreamTcpUtilStreamTest01(void)
182{
183 TcpReassemblyThreadCtx *ra_ctx = NULL;
184 TcpStream stream;
186 memset(&tv, 0x00, sizeof(tv));
187
188 StreamTcpUTInit(&ra_ctx);
189 StreamTcpUTSetupStream(&stream, 1);
190
191 FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1);
192 FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1);
193 FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1);
194
195 TcpSegment *seg = RB_MIN(TCPSEG, &stream.seg_tree);
196 FAIL_IF_NULL(seg);
197 FAIL_IF(seg->seq != 2);
198
199 seg = TCPSEG_RB_NEXT(seg);
200 FAIL_IF_NULL(seg);
201 FAIL_IF(seg->seq != 7);
202
203 seg = TCPSEG_RB_NEXT(seg);
204 FAIL_IF_NULL(seg);
205 FAIL_IF(seg->seq != 12);
206
207 StreamTcpUTClearStream(&stream);
208 StreamTcpUTDeinit(ra_ctx);
209 PASS;
210}
211
212static int StreamTcpUtilStreamTest02(void)
213{
214 TcpReassemblyThreadCtx *ra_ctx = NULL;
215 TcpStream stream;
217 memset(&tv, 0x00, sizeof(tv));
218
219 StreamTcpUTInit(&ra_ctx);
220 StreamTcpUTSetupStream(&stream, 1);
221
222 FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1);
223 FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1);
224 FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1);
225
226 TcpSegment *seg = RB_MIN(TCPSEG, &stream.seg_tree);
227 FAIL_IF_NULL(seg);
228 FAIL_IF(seg->seq != 2);
229
230 seg = TCPSEG_RB_NEXT(seg);
231 FAIL_IF_NULL(seg);
232 FAIL_IF(seg->seq != 7);
233
234 seg = TCPSEG_RB_NEXT(seg);
235 FAIL_IF_NULL(seg);
236 FAIL_IF(seg->seq != 12);
237
238 StreamTcpUTClearStream(&stream);
239 StreamTcpUTDeinit(ra_ctx);
240 PASS;
241}
242
243#endif
244
246{
247#ifdef UNITTESTS
248 UtRegisterTest("StreamTcpUtilTest01", StreamTcpUtilTest01);
249 UtRegisterTest("StreamTcpUtilStreamTest01", StreamTcpUtilStreamTest01);
250 UtRegisterTest("StreamTcpUtilStreamTest02", StreamTcpUtilStreamTest02);
251#endif /* UNITTESTS */
252}
253
uint8_t len
TcpStreamCnf stream_config
Definition stream-tcp.c:219
ThreadVars * tv
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
void IPPairInitConfig(bool quiet)
initialize the configuration
Definition ippair.c:162
int StreamTcpReassembleInsertSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, TcpSegment *seg, Packet *p, uint8_t *pkt_data, uint16_t pkt_datalen)
#define TCP_SEG_LEN(seg)
#define STREAMTCP_SET_RA_BASE_SEQ(stream, seq)
uint32_t seq
int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p)
Insert a TCP packet data into the stream reassembly engine.
void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *ra_ctx)
TcpSegment * StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *)
get a segment from the pool
TcpReassemblyThreadCtx * StreamTcpReassembleInitThreadCtx(ThreadVars *tv)
void StreamTcpUTSetupSession(TcpSession *ssn)
void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn)
void StreamTcpUtilRegisterTests(void)
void StreamTcpUTClearSession(TcpSession *ssn)
int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len)
void StreamTcpUTClearStream(TcpStream *s)
void StreamTcpUTInitInline(void)
int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
int StreamTcpUTAddPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
wrapper for StreamTcpReassembleHandleSegmentHandleData
void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx)
void StreamTcpSessionCleanup(TcpSession *ssn)
Session cleanup function. Does not free the ssn.
Definition stream-tcp.c:327
void StreamTcpStreamCleanup(TcpStream *stream)
Definition stream-tcp.c:300
void StreamTcpFreeConfig(bool quiet)
Definition stream-tcp.c:859
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition stream-tcp.c:488
#define STREAMTCP_INIT_FLAG_INLINE
Definition stream-tcp.h:41
union PacketL4::L4Hdrs hdrs
struct PacketL4 l4
Definition decode.h:601
uint8_t * payload
Definition decode.h:605
uint16_t payload_len
Definition decode.h:606
uint32_t th_seq
Definition decode-tcp.h:152
uint32_t th_ack
Definition decode-tcp.h:153
uint8_t flags
Definition stream-tcp.h:65
StreamingBuffer sb
struct TCPSEG seg_tree
Per thread variable structure.
Definition threadvars.h:58
#define RB_MIN(name, x)
Definition tree.h:778
TCPHdr * tcph
Definition decode.h:469
#define STREAMING_BUFFER_INITIALIZER
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.