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  * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
23  */
24 
25 #ifndef __STREAM_TCP_H__
26 #define __STREAM_TCP_H__
27 
28 #include "stream-tcp-private.h"
29 
30 #include "stream.h"
31 #include "stream-tcp-reassemble.h"
32 
33 #define STREAM_VERBOSE    FALSE
34 /* Flag to indicate that the checksum validation for the stream engine
35    has been enabled */
36 #define STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION    BIT_U8(0)
37 #define STREAMTCP_INIT_FLAG_DROP_INVALID           BIT_U8(1)
38 #define STREAMTCP_INIT_FLAG_BYPASS                 BIT_U8(2)
39 #define STREAMTCP_INIT_FLAG_INLINE                 BIT_U8(3)
40 
41 /*global flow data*/
42 typedef struct TcpStreamCnf_ {
43     /** stream tracking
44      *
45      * max stream mem usage
46      */
47     SC_ATOMIC_DECLARE(uint64_t, memcap);
48     SC_ATOMIC_DECLARE(uint64_t, reassembly_memcap); /**< max memory usage for stream reassembly */
49 
50     uint16_t stream_init_flags; /**< new stream flags will be initialized to this */
51 
52     /* coccinelle: TcpStreamCnf:flags:STREAMTCP_INIT_ */
53     uint8_t flags;
54     uint8_t max_synack_queued;
55 
56     uint32_t prealloc_sessions; /**< ssns to prealloc per stream thread */
57     uint32_t prealloc_segments; /**< segments to prealloc per stream thread */
58     int midstream;
59     int async_oneside;
60     uint32_t reassembly_depth;  /**< Depth until when we reassemble the stream */
61 
62     uint16_t reassembly_toserver_chunk_size;
63     uint16_t reassembly_toclient_chunk_size;
64 
65     bool streaming_log_api;
66 
67     StreamingBufferConfig sbcnf;
68 } TcpStreamCnf;
69 
70 typedef struct StreamTcpThread_ {
71     int ssn_pool_id;
72 
73     /** queue for pseudo packet(s) that were created in the stream
74      *  process and need further handling. Currently only used when
75      *  receiving (valid) RST packets */
76     PacketQueueNoLock pseudo_queue;
77 
78     uint16_t counter_tcp_sessions;
79     /** sessions not picked up because memcap was reached */
80     uint16_t counter_tcp_ssn_memcap;
81     /** pseudo packets processed */
82     uint16_t counter_tcp_pseudo;
83     /** pseudo packets failed to setup */
84     uint16_t counter_tcp_pseudo_failed;
85     /** packets rejected because their csum is invalid */
86     uint16_t counter_tcp_invalid_checksum;
87     /** TCP packets with no associated flow */
88     uint16_t counter_tcp_no_flow;
89     /** sessions reused */
90     uint16_t counter_tcp_reused_ssn;
91     /** syn pkts */
92     uint16_t counter_tcp_syn;
93     /** syn/ack pkts */
94     uint16_t counter_tcp_synack;
95     /** rst pkts */
96     uint16_t counter_tcp_rst;
97     /** midstream pickups */
98     uint16_t counter_tcp_midstream_pickups;
99     /** wrong thread */
100     uint16_t counter_tcp_wrong_thread;
101 
102     /** tcp reassembly thread data */
103     TcpReassemblyThreadCtx *ra_ctx;
104 } StreamTcpThread;
105 
106 extern TcpStreamCnf stream_config;
107 void StreamTcpInitConfig (char);
108 void StreamTcpFreeConfig(char);
109 void StreamTcpRegisterTests (void);
110 
111 void StreamTcpSessionPktFree (Packet *);
112 
113 void StreamTcpInitMemuse(void);
114 void StreamTcpIncrMemuse(uint64_t);
115 void StreamTcpDecrMemuse(uint64_t);
116 int StreamTcpSetMemcap(uint64_t);
117 uint64_t StreamTcpGetMemcap(void);
118 int StreamTcpCheckMemcap(uint64_t);
119 uint64_t StreamTcpMemuseCounter(void);
120 uint64_t StreamTcpReassembleMemuseGlobalCounter(void);
121 
122 Packet *StreamTcpPseudoSetup(Packet *, uint8_t *, uint32_t);
123 
124 int StreamTcpSegmentForEach(const Packet *p, uint8_t flag,
125                         StreamSegmentCallback CallbackFunc,
126                         void *data);
127 void StreamTcpReassembleConfigEnableOverlapCheck(void);
128 void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size);
129 
130 typedef int (*StreamReassembleRawFunc)(void *data, const uint8_t *input, const uint32_t input_len);
131 
132 int StreamReassembleLog(TcpSession *ssn, TcpStream *stream,
133         StreamReassembleRawFunc Callback, void *cb_data,
134         uint64_t progress_in,
135         uint64_t *progress_out, bool eof);
136 int StreamReassembleRaw(TcpSession *ssn, const Packet *p,
137         StreamReassembleRawFunc Callback, void *cb_data,
138         uint64_t *progress_out, bool respect_inspect_depth);
139 void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, uint64_t progress);
140 
141 void StreamTcpDetectLogFlush(ThreadVars *tv, StreamTcpThread *stt, Flow *f, Packet *p, PacketQueueNoLock *pq);
142 
143 const char *StreamTcpStateAsString(const enum TcpState);
144 const char *StreamTcpSsnStateAsString(const TcpSession *ssn);
145 
146 /** ------- Inline functions: ------ */
147 
148 /**
149   * \brief If we are on IPS mode, and got a drop action triggered from
150   * the IP only module, or from a reassembled msg and/or from an
151   * applayer detection, then drop the rest of the packets of the
152   * same stream and avoid inspecting it any further
153   * \param p pointer to the Packet to check
154   * \retval 1 if we must drop this stream
155   * \retval 0 if the stream still legal
156   */
StreamTcpCheckFlowDrops(Packet * p)157 static inline int StreamTcpCheckFlowDrops(Packet *p)
158 {
159     /* If we are on IPS mode, and got a drop action triggered from
160      * the IP only module, or from a reassembled msg and/or from an
161      * applayer detection, then drop the rest of the packets of the
162      * same stream and avoid inspecting it any further */
163     if (EngineModeIsIPS() && (p->flow->flags & FLOW_ACTION_DROP))
164         return 1;
165 
166     return 0;
167 }
168 
169 enum {
170     /* stream has no segments for forced reassembly, nor for detection */
171     STREAM_HAS_UNPROCESSED_SEGMENTS_NONE = 0,
172     /* stream has no segments for forced reassembly, but only segments that
173      * have been sent for detection, but are stuck in the detection queues */
174     STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION = 1,
175 };
176 
177 TmEcode StreamTcp (ThreadVars *, Packet *, void *, PacketQueueNoLock *);
178 int StreamNeedsReassembly(const TcpSession *ssn, uint8_t direction);
179 TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **);
180 TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data);
181 void StreamTcpRegisterTests (void);
182 
183 int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
184                      PacketQueueNoLock *pq);
185 /* clear ssn and return to pool */
186 void StreamTcpSessionClear(void *ssnptr);
187 /* cleanup ssn, but don't free ssn */
188 void StreamTcpSessionCleanup(TcpSession *ssn);
189 /* cleanup stream, but don't free the stream */
190 void StreamTcpStreamCleanup(TcpStream *stream);
191 /* check if bypass is enabled */
192 int StreamTcpBypassEnabled(void);
193 int StreamTcpInlineDropInvalid(void);
194 int StreamTcpInlineMode(void);
195 
196 int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, const void *tcp_ssn);
197 
198 void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction,
199         const uint32_t progress);
200 
201 #endif /* __STREAM_TCP_H__ */
202 
203