suricata
stream-tcp-private.h
Go to the documentation of this file.
1/* Copyright (C) 2007-2010 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
24#ifndef SURICATA_STREAM_TCP_PRIVATE_H
25#define SURICATA_STREAM_TCP_PRIVATE_H
26
27#include "util-pool-thread.h"
29
30#define STREAMTCP_QUEUE_FLAG_TS 0x01
31#define STREAMTCP_QUEUE_FLAG_WS 0x02
32#define STREAMTCP_QUEUE_FLAG_SACK 0x04
33
34/** Tracking SYNs and SYN/ACKs */
35typedef struct TcpStateQueue_ {
36 uint8_t flags;
37 uint8_t wscale;
38 uint16_t win;
39 uint32_t seq;
40 uint32_t ack;
41 uint32_t ts;
42 uint32_t pkt_ts;
45
46typedef struct StreamTcpSackRecord {
47 uint32_t le; /**< left edge, host order */
48 uint32_t re; /**< right edge, host order */
51
53
54/* red-black tree prototype for SACK records */
57
58#define TCPSEG_PKT_HDR_DEFAULT_SIZE 64
59
60/*
61 * Struct to add the additional information required to use TcpSegments to dump
62 * a packet capture to file with the stream-pcap-log output option. This is only
63 * used if the session-dump option is enabled.
64 */
71
72typedef struct TcpSegment {
74 uint16_t payload_len; /**< actual size of the payload */
75 uint32_t seq;
77 StreamingBufferSegment sbseg;
79} __attribute__((__packed__)) TcpSegment;
80
81/** \brief compare function for the Segment tree
82 *
83 * Main sort point is the sequence number. When sequence numbers
84 * are equal compare payload_len as well. This way the tree is
85 * sorted by seq, and in case of duplicate seqs we are sorted
86 * small to large.
87 */
88int TcpSegmentCompare(struct TcpSegment *a, struct TcpSegment *b);
89
90/* red-black tree prototype for TcpSegment */
93
94#define TCP_SEG_LEN(seg) (seg)->payload_len
95#define TCP_SEG_OFFSET(seg) (seg)->sbseg.stream_offset
96
97#define SEG_SEQ_RIGHT_EDGE(seg) ((seg)->seq + TCP_SEG_LEN((seg)))
98
99/* get right edge of sequence space of seen segments.
100 * Only use if STREAM_HAS_SEEN_DATA is true. */
101#define STREAM_SEQ_RIGHT_EDGE(stream) (stream)->segs_right_edge
102#define STREAM_RIGHT_EDGE(stream) (STREAM_BASE_OFFSET((stream)) + (STREAM_SEQ_RIGHT_EDGE((stream)) - (stream)->base_seq))
103/* return true if we have seen data. */
104#define STREAM_HAS_SEEN_DATA(stream) StreamingBufferHasData(&(stream)->sb)
105
106typedef struct TcpStream_ {
107 uint16_t flags:12; /**< Flag specific to the stream e.g. Timestamp */
108 /* coccinelle: TcpStream:flags:STREAMTCP_STREAM_FLAG_ */
109 uint16_t wscale:4; /**< wscale setting in this direction, 4 bits as max val is 15 */
110 uint8_t os_policy; /**< target based OS policy used for reassembly and handling packets*/
111 uint8_t tcp_flags; /**< TCP flags seen */
112
113 uint32_t isn; /**< initial sequence number */
114 uint32_t next_seq; /**< next expected sequence number */
115 uint32_t last_ack; /**< last ack'd sequence number in this stream */
116 uint32_t next_win; /**< next max seq within window */
117 uint32_t window; /**< current window setting, after wscale is applied */
118
119 uint32_t last_ts; /**< Time stamp (TSVAL) of the last seen packet for this stream*/
120 uint32_t last_pkt_ts; /**< Time of last seen packet for this stream (needed for PAWS update)
121 This will be used to validate the last_ts, when connection has been idle for
122 longer time.(RFC 1323)*/
123 /* reassembly */
124 uint32_t base_seq; /**< seq where we are left with reassembly. Matches STREAM_BASE_OFFSET below.
125 */
126
127 uint32_t app_progress_rel; /**< app-layer progress relative to STREAM_BASE_OFFSET */
128 uint32_t raw_progress_rel; /**< raw reassembly progress relative to STREAM_BASE_OFFSET */
129 uint32_t log_progress_rel; /**< streaming logger progress relative to STREAM_BASE_OFFSET */
130
131 uint32_t min_inspect_depth; /**< min inspect size set by the app layer, to make sure enough data
132 * remains available for inspection together with app layer buffers */
133 uint32_t data_required; /**< data required from STREAM_APP_PROGRESS before calling app-layer again */
134
136 struct TCPSEG seg_tree; /**< red black tree of TCP segments. Data is stored in TcpStream::sb */
138
139 uint32_t sack_size; /**< combined size of the SACK ranges currently in our tree. Updated
140 * at INSERT/REMOVE time. */
141 struct TCPSACK sack_tree; /**< red back tree of TCP SACK records. */
143
144#define STREAM_BASE_OFFSET(stream) ((stream)->sb.region.stream_offset)
145#define STREAM_APP_PROGRESS(stream) (STREAM_BASE_OFFSET((stream)) + (stream)->app_progress_rel)
146#define STREAM_RAW_PROGRESS(stream) (STREAM_BASE_OFFSET((stream)) + (stream)->raw_progress_rel)
147#define STREAM_LOG_PROGRESS(stream) (STREAM_BASE_OFFSET((stream)) + (stream)->log_progress_rel)
148
149/* from /usr/include/netinet/tcp.h */
164
165/*
166 * Per SESSION flags
167 */
168
169/** Flag for mid stream session */
170#define STREAMTCP_FLAG_MIDSTREAM BIT_U32(0)
171/** Flag for mid stream established session */
172#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED BIT_U32(1)
173/** Flag for mid session when syn/ack is received */
174#define STREAMTCP_FLAG_MIDSTREAM_SYNACK BIT_U32(2)
175/** Flag for TCP Timestamp option */
176#define STREAMTCP_FLAG_TIMESTAMP BIT_U32(3)
177/** Server supports wscale (even though it can be 0) */
178#define STREAMTCP_FLAG_SERVER_WSCALE BIT_U32(4)
179/** Closed by RST */
180#define STREAMTCP_FLAG_CLOSED_BY_RST BIT_U32(5)
181/** Flag to indicate that the session is handling asynchronous stream.*/
182#define STREAMTCP_FLAG_ASYNC BIT_U32(6)
183/** Flag to indicate we're dealing with 4WHS: SYN, SYN, SYN/ACK, ACK
184 * (http://www.breakingpointsystems.com/community/blog/tcp-portals-the-three-way-handshake-is-a-lie) */
185#define STREAMTCP_FLAG_4WHS BIT_U32(7)
186/** Flag to indicate that this session is possible trying to evade the detection
187 * (http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make.html) */
188#define STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT BIT_U32(8)
189/** Flag to indicate the client (SYN pkt) permits SACK */
190#define STREAMTCP_FLAG_CLIENT_SACKOK BIT_U32(9)
191/** Flag to indicate both sides of the session permit SACK (SYN + SYN/ACK) */
192#define STREAMTCP_FLAG_SACKOK BIT_U32(10)
193/** Session is in "lossy" state, be liberal */
194#define STREAMTCP_FLAG_LOSSY_BE_LIBERAL BIT_U32(11)
195/** 3WHS confirmed by server -- if suri sees 3whs ACK but server doesn't (pkt
196 * is lost on the way to server), SYN/ACK is retransmitted. If server sends
197 * normal packet we assume 3whs to be completed. Only used for SYN/ACK resend
198 * event. */
199#define STREAMTCP_FLAG_3WHS_CONFIRMED BIT_U32(12)
200/** App Layer tracking/reassembly is disabled */
201#define STREAMTCP_FLAG_APP_LAYER_DISABLED BIT_U32(13)
202/** Stream can be bypass */
203#define STREAMTCP_FLAG_BYPASS BIT_U32(14)
204/** SSN uses TCP Fast Open */
205#define STREAMTCP_FLAG_TCP_FAST_OPEN BIT_U32(15)
206/** SYN/ACK ignored the data while ACKing the SYN */
207#define STREAMTCP_FLAG_TFO_DATA_IGNORED BIT_U32(16)
208/* zero window probe */
209#define STREAMTCP_FLAG_ZWP_TS BIT_U32(17)
210#define STREAMTCP_FLAG_ZWP_TC BIT_U32(18)
211
212/*
213 * Per STREAM flags
214 */
215
216/** Flag to indicate that we have seen gap on the stream */
217#define STREAMTCP_STREAM_FLAG_HAS_GAP BIT_U16(0)
218/** Flag to avoid stream reassembly/app layer inspection for the stream */
219#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY BIT_U16(1)
220/** we received a keep alive */
221#define STREAMTCP_STREAM_FLAG_KEEPALIVE BIT_U16(2)
222/** Stream has reached it's reassembly depth, all further packets are ignored */
223#define STREAMTCP_STREAM_FLAG_DEPTH_REACHED BIT_U16(3)
224/** Trigger reassembly next time we need 'raw' */
225#define STREAMTCP_STREAM_FLAG_TRIGGER_RAW BIT_U16(4)
226/** Stream supports TIMESTAMP -- used to set ssn STREAMTCP_FLAG_TIMESTAMP
227 * flag. */
228#define STREAMTCP_STREAM_FLAG_TIMESTAMP BIT_U16(5)
229/** Flag to indicate the zero value of timestamp */
230#define STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP BIT_U16(6)
231/** App proto detection completed */
232#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED BIT_U16(7)
233/** App proto detection skipped */
234#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED BIT_U16(8)
235/** Raw reassembly disabled for new segments */
236#define STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED BIT_U16(9)
237/** Raw reassembly disabled completely */
238#define STREAMTCP_STREAM_FLAG_DISABLE_RAW BIT_U16(10)
239
240#define STREAMTCP_STREAM_FLAG_RST_RECV BIT_U16(11)
241
242/** NOTE: flags field is 12 bits */
243
244
245
246
247#define PAWS_24DAYS 2073600 /**< 24 days in seconds */
248
249#define PKT_IS_IN_RIGHT_DIR(ssn, p) ((ssn)->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK ? \
250 PKT_IS_TOSERVER(p) ? (p)->flowflags &= ~FLOW_PKT_TOSERVER \
251 (p)->flowflags |= FLOW_PKT_TOCLIENT : (p)->flowflags &= ~FLOW_PKT_TOCLIENT \
252 (p)->flowflags |= FLOW_PKT_TOSERVER : 0)
253
254/* Macro's for comparing Sequence numbers
255 * Page 810 from TCP/IP Illustrated, Volume 2. */
256#define SEQ_EQ(a,b) ((int32_t)((a) - (b)) == 0)
257#define SEQ_LT(a,b) ((int32_t)((a) - (b)) < 0)
258#define SEQ_LEQ(a,b) ((int32_t)((a) - (b)) <= 0)
259#define SEQ_GT(a,b) ((int32_t)((a) - (b)) > 0)
260#define SEQ_GEQ(a,b) ((int32_t)((a) - (b)) >= 0)
261#define SEQ_MIN(a, b) (SEQ_LT((a), (b)) ? (a) : (b))
262#define SEQ_MAX(a, b) (SEQ_GT((a), (b)) ? (a) : (b))
263
264#define STREAMTCP_SET_RA_BASE_SEQ(stream, seq) { \
265 do { \
266 (stream)->base_seq = (seq) + 1; \
267 } while(0); \
268}
269
270#define StreamTcpSetEvent(p, e) \
271 { \
272 if ((p)->flags & PKT_STREAM_NO_EVENTS) { \
273 SCLogDebug("not setting event %d on pkt %p (%" PRIu64 "), " \
274 "stream in known bad condition", \
275 (e), p, (p)->pcap_cnt); \
276 } else { \
277 SCLogDebug("setting event %d on pkt %p (%" PRIu64 ")", (e), p, (p)->pcap_cnt); \
278 ENGINE_SET_EVENT((p), (e)); \
279 p->l4.vars.tcp.stream_pkt_flags |= STREAM_PKT_FLAG_EVENTSET; \
280 } \
281 }
282
283typedef struct TcpSession_ {
285 uint8_t state:4; /**< tcp state from state enum */
286 uint8_t pstate:4; /**< previous state */
287 uint8_t queue_len; /**< length of queue list below */
289 /** track all the tcp flags we've seen */
291 uint16_t urg_offset_ts; /**< SEQ offset from accepted OOB urg bytes */
292 uint16_t urg_offset_tc; /**< SEQ offset from accepted OOB urg bytes */
293 /* coccinelle: TcpSession:flags:STREAMTCP_FLAG */
294 uint32_t flags;
295 uint32_t reassembly_depth; /**< reassembly depth for the stream */
298 TcpStateQueue *queue; /**< list of SYN/ACK candidates */
300
301#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream) \
302 ((stream)->flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)
303#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream) \
304 ((stream)->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)
305#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream) \
306 ((stream)->flags &= ~STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED);
307#define StreamTcpDisableAppLayerReassembly(ssn) do { \
308 SCLogDebug("setting STREAMTCP_FLAG_APP_LAYER_DISABLED on ssn %p", ssn); \
309 ((ssn)->flags |= STREAMTCP_FLAG_APP_LAYER_DISABLED); \
310 } while (0);
311
312#define STREAM_PKT_FLAG_RETRANSMISSION BIT_U16(0)
313#define STREAM_PKT_FLAG_SPURIOUS_RETRANSMISSION BIT_U16(1)
314#define STREAM_PKT_FLAG_STATE_UPDATE BIT_U16(2)
315#define STREAM_PKT_FLAG_KEEPALIVE BIT_U16(3)
316#define STREAM_PKT_FLAG_KEEPALIVEACK BIT_U16(4)
317#define STREAM_PKT_FLAG_WINDOWUPDATE BIT_U16(5)
318#define STREAM_PKT_FLAG_EVENTSET BIT_U16(6)
319#define STREAM_PKT_FLAG_DUP_ACK BIT_U16(7)
320#define STREAM_PKT_FLAG_DSACK BIT_U16(8)
321#define STREAM_PKT_FLAG_ACK_UNSEEN_DATA BIT_U16(9)
322#define STREAM_PKT_FLAG_TCP_SESSION_REUSE BIT_U16(10)
323#define STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE BIT_U16(11)
324#define STREAM_PKT_FLAG_TCP_ZERO_WIN_PROBE_ACK BIT_U16(12)
325
326#define STREAM_PKT_FLAG_SET(p, f) (p)->l4.vars.tcp.stream_pkt_flags |= (f)
327
328#endif /* SURICATA_STREAM_TCP_PRIVATE_H */
struct PrefilterEngineFlowbits __attribute__
DNP3 application header.
struct TcpStream_ TcpStream
@ TCP_ESTABLISHED
@ TCP_SYN_RECV
@ TCP_LAST_ACK
@ TCP_CLOSE_WAIT
@ TCP_CLOSING
@ TCP_CLOSED
@ TCP_FIN_WAIT2
@ TCP_TIME_WAIT
@ TCP_SYN_SENT
@ TCP_FIN_WAIT1
struct TcpSession_ TcpSession
int TcpSegmentCompare(struct TcpSegment *a, struct TcpSegment *b)
compare function for the Segment tree
int TcpSackCompare(struct StreamTcpSackRecord *a, struct StreamTcpSackRecord *b)
struct TcpSegmentPcapHdrStorage_ TcpSegmentPcapHdrStorage
struct TcpStateQueue_ TcpStateQueue
RB_ENTRY(StreamTcpSackRecord) rb
StreamingBufferSegment sbseg
RB_ENTRY(TcpSegment) __attribute__((__packed__)) rb
TcpSegmentPcapHdrStorage * pcap_hdr_storage
PoolThreadId pool_id
uint16_t payload_len
TcpStateQueue * queue
uint32_t reassembly_depth
PoolThreadId pool_id
struct TcpStateQueue_ * next
uint32_t log_progress_rel
uint32_t min_inspect_depth
StreamingBuffer sb
struct TCPSACK sack_tree
uint32_t raw_progress_rel
struct TCPSEG seg_tree
uint32_t segs_right_edge
uint32_t data_required
uint32_t app_progress_rel
#define RB_PROTOTYPE(name, type, field, cmp)
Definition tree.h:385
#define RB_HEAD(name, type)
Definition tree.h:300
uint16_t PoolThreadId