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 
28 #include "stream-tcp-reassemble.h"
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"
37 #include "util-unittest-helper.h"
38 #include "ippair.h"
39 
40 #ifdef UNITTESTS
41 
42 /* unittest helper functions */
43 
45 {
48  *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL);
49 }
50 
52 {
56 }
57 
60 }
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 
79 void 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 
92 {
94 }
95 
96 /** \brief wrapper for StreamTcpReassembleHandleSegmentHandleData */
97 int 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->tcph->th_seq = htonl(seq);
104  p->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 
113 int 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->tcph->th_seq = htonl(seq);
128 
129  if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_SEQ(p), p->payload, p->payload_len) < 0)
130  return -1;
131 
132  UTHFreePacket(p);
133  return 0;
134 }
135 
136 int 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->tcph->th_seq = htonl(seq);
153 
154  if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_SEQ(p), p->payload, p->payload_len) < 0)
155  return -1;
156  UTHFreePacket(p);
157  return 0;
158 }
159 
160 /* tests */
161 
162 static 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;
175 end:
176  StreamTcpUTDeinit(ra_ctx);
177  return ret;
178 }
179 
180 
181 static int StreamTcpUtilStreamTest01(void)
182 {
183  TcpReassemblyThreadCtx *ra_ctx = NULL;
184  TcpStream stream;
185  ThreadVars tv;
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 
212 static int StreamTcpUtilStreamTest02(void)
213 {
214  TcpReassemblyThreadCtx *ra_ctx = NULL;
215  TcpStream stream;
216  ThreadVars tv;
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 
StreamTcpUTAddPayload
int StreamTcpUTAddPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
wrapper for StreamTcpReassembleHandleSegmentHandleData
Definition: stream-tcp-util.c:97
TcpStream_
Definition: stream-tcp-private.h:94
len
uint8_t len
Definition: app-layer-dnp3.h:2
ippair.h
StreamTcpUTDeinit
void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx)
Definition: stream-tcp-util.c:51
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
TcpStream_::isn
uint32_t isn
Definition: stream-tcp-private.h:101
StreamTcpGetSegment
TcpSegment * StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *)
get a segment from the pool
Definition: stream-tcp-reassemble.c:1833
TCP_SEG_LEN
#define TCP_SEG_LEN(seg)
Definition: stream-tcp-private.h:82
stream-tcp-inline.h
StreamTcpUTClearStream
void StreamTcpUTClearStream(TcpStream *s)
Definition: stream-tcp-util.c:91
stream-tcp.h
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
StreamTcpReassembleInsertSegment
int StreamTcpReassembleInsertSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, TcpSegment *seg, Packet *p, uint32_t pkt_seq, uint8_t *pkt_data, uint16_t pkt_datalen)
Definition: stream-tcp-list.c:557
TcpStream_::seg_tree
struct TCPSEG seg_tree
Definition: stream-tcp-private.h:123
seq
uint32_t seq
Definition: stream-tcp-private.h:2
Packet_::payload
uint8_t * payload
Definition: decode.h:543
TcpStreamCnf_::flags
uint8_t flags
Definition: stream-tcp.h:53
TcpStreamCnf_::sbcnf
StreamingBufferConfig sbcnf
Definition: stream-tcp.h:67
StreamTcpUtilRegisterTests
void StreamTcpUtilRegisterTests(void)
Definition: stream-tcp-util.c:245
RB_MIN
#define RB_MIN(name, x)
Definition: tree.h:778
stream-tcp-reassemble.h
TcpSegment::seq
uint32_t seq
Definition: stream-tcp-private.h:64
StreamTcpStreamCleanup
void StreamTcpStreamCleanup(TcpStream *stream)
Definition: stream-tcp.c:202
UTHBuildPacketReal
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...
Definition: util-unittest-helper.c:241
StreamTcpUTInitInline
void StreamTcpUTInitInline(void)
Definition: stream-tcp-util.c:58
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:544
util-unittest.h
util-unittest-helper.h
util-memcmp.h
StreamTcpReassembleInitThreadCtx
TcpReassemblyThreadCtx * StreamTcpReassembleInitThreadCtx(ThreadVars *tv)
Definition: stream-tcp-reassemble.c:429
StreamTcpUTInit
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
Definition: stream-tcp-util.c:44
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-print.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
StreamTcpUTSetupStream
void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn)
Definition: stream-tcp-util.c:79
IPPairInitConfig
void IPPairInitConfig(char quiet)
initialize the configuration
Definition: ippair.c:168
TRUE
#define TRUE
Definition: suricata-common.h:33
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:119
TCP_GET_SEQ
#define TCP_GET_SEQ(p)
Definition: decode-tcp.h:112
TcpSegment
Definition: stream-tcp-private.h:61
Packet_
Definition: decode.h:411
StreamTcpFreeConfig
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
StreamTcpReassembleFreeThreadCtx
void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *ra_ctx)
Definition: stream-tcp-reassemble.c:470
StreamingBuffer_
Definition: util-streaming-buffer.h:95
StreamTcpReassembleHandleSegmentHandleData
int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p)
Insert a packets TCP data into the stream reassembly engine.
Definition: stream-tcp-reassemble.c:593
StreamTcpUTClearSession
void StreamTcpUTClearSession(TcpSession *ssn)
Definition: stream-tcp-util.c:71
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
STREAMTCP_SET_RA_BASE_SEQ
#define STREAMTCP_SET_RA_BASE_SEQ(stream, seq)
Definition: stream-tcp-private.h:243
suricata-common.h
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:525
TcpStream_::base_seq
uint32_t base_seq
Definition: stream-tcp-private.h:112
TcpStream_::sb
StreamingBuffer sb
Definition: stream-tcp-private.h:122
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:272
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
StreamTcpUTAddSegmentWithPayload
int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
Definition: stream-tcp-util.c:113
StreamTcpUTSetupSession
void StreamTcpUTSetupSession(TcpSession *ssn)
Definition: stream-tcp-util.c:62
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:271
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:484
StreamTcpUTAddSegmentWithByte
int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len)
Definition: stream-tcp-util.c:136
STREAMING_BUFFER_INITIALIZER
#define STREAMING_BUFFER_INITIALIZER(cfg)
Definition: util-streaming-buffer.h:111
StreamTcpSessionCleanup
void StreamTcpSessionCleanup(TcpSession *ssn)
Session cleanup function. Does not free the ssn.
Definition: stream-tcp.c:215
stream-tcp-util.h
StreamTcpInitConfig
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:60
TcpSession_
Definition: stream-tcp-private.h:260
STREAMTCP_INIT_FLAG_INLINE
#define STREAMTCP_INIT_FLAG_INLINE
Definition: stream-tcp.h:39