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 {
46  StreamTcpInitConfig(true);
47  IPPairInitConfig(true);
48  *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL);
49 }
50 
52 {
54  StreamTcpFreeConfig(true);
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->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 
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->l4.hdrs.tcph->th_seq = htonl(seq);
128 
129  if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_RAW_SEQ(p->l4.hdrs.tcph),
130  p->payload, p->payload_len) < 0)
131  return -1;
132 
133  UTHFreePacket(p);
134  return 0;
135 }
136 
137 int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len)
138 {
139  TcpSegment *s = StreamTcpGetSegment(tv, ra_ctx);
140  if (s == NULL) {
141  return -1;
142  }
143 
144  s->seq = seq;
145  TCP_SEG_LEN(s) = len;
146  uint8_t buf[len];
147  memset(buf, byte, len);
148 
149  Packet *p = UTHBuildPacketReal(buf, len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
150  if (p == NULL) {
151  return -1;
152  }
153  p->l4.hdrs.tcph->th_seq = htonl(seq);
154 
155  if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p, TCP_GET_RAW_SEQ(p->l4.hdrs.tcph),
156  p->payload, p->payload_len) < 0)
157  return -1;
158  UTHFreePacket(p);
159  return 0;
160 }
161 
162 /* tests */
163 
164 static int StreamTcpUtilTest01(void)
165 {
166  int ret = 0;
167  TcpReassemblyThreadCtx *ra_ctx = NULL;
168 
169  StreamTcpUTInit(&ra_ctx);
170 
171  if (ra_ctx == NULL) {
172  printf("ra_ctx is NULL: ");
173  goto end;
174  }
175 
176  ret = 1;
177 end:
178  StreamTcpUTDeinit(ra_ctx);
179  return ret;
180 }
181 
182 
183 static int StreamTcpUtilStreamTest01(void)
184 {
185  TcpReassemblyThreadCtx *ra_ctx = NULL;
186  TcpStream stream;
187  ThreadVars tv;
188  memset(&tv, 0x00, sizeof(tv));
189 
190  StreamTcpUTInit(&ra_ctx);
191  StreamTcpUTSetupStream(&stream, 1);
192 
193  FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1);
194  FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1);
195  FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1);
196 
197  TcpSegment *seg = RB_MIN(TCPSEG, &stream.seg_tree);
198  FAIL_IF_NULL(seg);
199  FAIL_IF(seg->seq != 2);
200 
201  seg = TCPSEG_RB_NEXT(seg);
202  FAIL_IF_NULL(seg);
203  FAIL_IF(seg->seq != 7);
204 
205  seg = TCPSEG_RB_NEXT(seg);
206  FAIL_IF_NULL(seg);
207  FAIL_IF(seg->seq != 12);
208 
209  StreamTcpUTClearStream(&stream);
210  StreamTcpUTDeinit(ra_ctx);
211  PASS;
212 }
213 
214 static int StreamTcpUtilStreamTest02(void)
215 {
216  TcpReassemblyThreadCtx *ra_ctx = NULL;
217  TcpStream stream;
218  ThreadVars tv;
219  memset(&tv, 0x00, sizeof(tv));
220 
221  StreamTcpUTInit(&ra_ctx);
222  StreamTcpUTSetupStream(&stream, 1);
223 
224  FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1);
225  FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1);
226  FAIL_IF(StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1);
227 
228  TcpSegment *seg = RB_MIN(TCPSEG, &stream.seg_tree);
229  FAIL_IF_NULL(seg);
230  FAIL_IF(seg->seq != 2);
231 
232  seg = TCPSEG_RB_NEXT(seg);
233  FAIL_IF_NULL(seg);
234  FAIL_IF(seg->seq != 7);
235 
236  seg = TCPSEG_RB_NEXT(seg);
237  FAIL_IF_NULL(seg);
238  FAIL_IF(seg->seq != 12);
239 
240  StreamTcpUTClearStream(&stream);
241  StreamTcpUTDeinit(ra_ctx);
242  PASS;
243 }
244 
245 #endif
246 
248 {
249 #ifdef UNITTESTS
250  UtRegisterTest("StreamTcpUtilTest01", StreamTcpUtilTest01);
251  UtRegisterTest("StreamTcpUtilStreamTest01", StreamTcpUtilStreamTest01);
252  UtRegisterTest("StreamTcpUtilStreamTest02", StreamTcpUtilStreamTest02);
253 #endif /* UNITTESTS */
254 }
255 
TCP_GET_RAW_SEQ
#define TCP_GET_RAW_SEQ(tcph)
Definition: decode-tcp.h:80
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:106
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:113
StreamTcpGetSegment
TcpSegment * StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *)
get a segment from the pool
Definition: stream-tcp-reassemble.c:2078
IPPairInitConfig
void IPPairInitConfig(bool quiet)
initialize the configuration
Definition: ippair.c:162
TCP_SEG_LEN
#define TCP_SEG_LEN(seg)
Definition: stream-tcp-private.h:94
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:637
TcpStream_::seg_tree
struct TCPSEG seg_tree
Definition: stream-tcp-private.h:136
seq
uint32_t seq
Definition: stream-tcp-private.h:2
Packet_::payload
uint8_t * payload
Definition: decode.h:580
TcpStreamCnf_::flags
uint8_t flags
Definition: stream-tcp.h:55
StreamTcpUtilRegisterTests
void StreamTcpUtilRegisterTests(void)
Definition: stream-tcp-util.c:247
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:75
StreamTcpStreamCleanup
void StreamTcpStreamCleanup(TcpStream *stream)
Definition: stream-tcp.c:300
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:219
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:260
StreamTcpUTInitInline
void StreamTcpUTInitInline(void)
Definition: stream-tcp-util.c:58
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:581
util-unittest.h
util-unittest-helper.h
TCPHdr_::th_ack
uint32_t th_ack
Definition: decode-tcp.h:153
util-memcmp.h
StreamTcpReassembleInitThreadCtx
TcpReassemblyThreadCtx * StreamTcpReassembleInitThreadCtx(ThreadVars *tv)
Definition: stream-tcp-reassemble.c:556
StreamTcpUTInit
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
Definition: stream-tcp-util.c:44
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:461
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
TCPHdr_::th_seq
uint32_t th_seq
Definition: decode-tcp.h:152
util-print.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
StreamTcpUTSetupStream
void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn)
Definition: stream-tcp-util.c:79
TcpSegment
Definition: stream-tcp-private.h:72
Packet_
Definition: decode.h:479
Packet_::l4
struct PacketL4 l4
Definition: decode.h:576
StreamTcpReassembleFreeThreadCtx
void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *ra_ctx)
Definition: stream-tcp-reassemble.c:595
STREAMING_BUFFER_INITIALIZER
#define STREAMING_BUFFER_INITIALIZER
Definition: util-streaming-buffer.h:137
StreamingBuffer_
Definition: util-streaming-buffer.h:108
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:736
StreamTcpUTClearSession
void StreamTcpUTClearSession(TcpSession *ssn)
Definition: stream-tcp-util.c:71
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:792
STREAMTCP_SET_RA_BASE_SEQ
#define STREAMTCP_SET_RA_BASE_SEQ(stream, seq)
Definition: stream-tcp-private.h:264
suricata-common.h
TcpStream_::base_seq
uint32_t base_seq
Definition: stream-tcp-private.h:124
TcpStream_::sb
StreamingBuffer sb
Definition: stream-tcp-private.h:135
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:295
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
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
PacketL4::L4Hdrs::tcph
TCPHdr * tcph
Definition: decode.h:447
StreamTcpUTSetupSession
void StreamTcpUTSetupSession(TcpSession *ssn)
Definition: stream-tcp-util.c:62
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:294
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:467
StreamTcpUTAddSegmentWithByte
int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len)
Definition: stream-tcp-util.c:137
StreamTcpSessionCleanup
void StreamTcpSessionCleanup(TcpSession *ssn)
Session cleanup function. Does not free the ssn.
Definition: stream-tcp.c:327
stream-tcp-util.h
PacketL4::hdrs
union PacketL4::L4Hdrs hdrs
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:61
TcpSession_
Definition: stream-tcp-private.h:283
STREAMTCP_INIT_FLAG_INLINE
#define STREAMTCP_INIT_FLAG_INLINE
Definition: stream-tcp.h:41