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_REASSEMBLE_H__
26 #define __STREAM_TCP_REASSEMBLE_H__
27 
28 #include "stream-tcp-private.h"
29 #include "stream.h"
30 #include "app-layer-detect-proto.h"
31 #include "stream-tcp-private.h"
32 
33 /** Supported OS list and default OS policy is BSD */
34 enum
35 {
36     OS_POLICY_NONE = 1,
37     OS_POLICY_BSD,
38     OS_POLICY_BSD_RIGHT,
39     OS_POLICY_OLD_LINUX,
40     OS_POLICY_LINUX,
41     OS_POLICY_OLD_SOLARIS,
42     OS_POLICY_SOLARIS,
43     OS_POLICY_HPUX10,
44     OS_POLICY_HPUX11,
45     OS_POLICY_IRIX,
46     OS_POLICY_MACOS,
47     OS_POLICY_WINDOWS,
48     OS_POLICY_VISTA,
49     OS_POLICY_WINDOWS2K3,
50     OS_POLICY_FIRST,
51     OS_POLICY_LAST
52 };
53 
54 enum StreamUpdateDir {
55     UPDATE_DIR_PACKET,
56     UPDATE_DIR_OPPOSING,
57     UPDATE_DIR_BOTH,
58 };
59 
60 typedef struct TcpReassemblyThreadCtx_ {
61     void *app_tctx;
62 
63     int segment_thread_pool_id;
64 
65     /** TCP segments which are not being reassembled due to memcap was reached */
66     uint16_t counter_tcp_segment_memcap;
67     /** number of streams that stop reassembly because their depth is reached */
68     uint16_t counter_tcp_stream_depth;
69     /** count number of streams with a unrecoverable stream gap (missing pkts) */
70     uint16_t counter_tcp_reass_gap;
71 
72     /** count packet data overlaps */
73     uint16_t counter_tcp_reass_overlap;
74     /** count overlaps with different data */
75     uint16_t counter_tcp_reass_overlap_diff_data;
76 
77     uint16_t counter_tcp_reass_data_normal_fail;
78     uint16_t counter_tcp_reass_data_overlap_fail;
79     uint16_t counter_tcp_reass_list_fail;
80 } TcpReassemblyThreadCtx;
81 
82 #define OS_POLICY_DEFAULT   OS_POLICY_BSD
83 
84 void StreamTcpReassembleInitMemuse(void);
85 int StreamTcpReassembleHandleSegment(ThreadVars *, TcpReassemblyThreadCtx *, TcpSession *, TcpStream *, Packet *, PacketQueueNoLock *);
86 int StreamTcpReassembleInit(char);
87 void StreamTcpReassembleFree(char);
88 void StreamTcpReassembleRegisterTests(void);
89 TcpReassemblyThreadCtx *StreamTcpReassembleInitThreadCtx(ThreadVars *tv);
90 void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *);
91 int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
92                                  TcpSession *ssn, TcpStream *stream,
93                                  Packet *p, enum StreamUpdateDir dir);
94 
95 void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t);
96 
97 void StreamTcpSetSessionNoReassemblyFlag(TcpSession *, char);
98 void StreamTcpSetSessionBypassFlag(TcpSession *);
99 void StreamTcpSetDisableRawReassemblyFlag(TcpSession *, char);
100 
101 void StreamTcpSetOSPolicy(TcpStream *, Packet *);
102 
103 int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
104         TcpSession *ssn, TcpStream *stream, Packet *p);
105 int StreamTcpReassembleInsertSegment(ThreadVars *, TcpReassemblyThreadCtx *, TcpStream *, TcpSegment *, Packet *, uint32_t pkt_seq, uint8_t *pkt_data, uint16_t pkt_datalen);
106 TcpSegment *StreamTcpGetSegment(ThreadVars *, TcpReassemblyThreadCtx *);
107 
108 void StreamTcpReturnStreamSegments(TcpStream *);
109 void StreamTcpSegmentReturntoPool(TcpSegment *);
110 
111 void StreamTcpReassembleTriggerRawReassembly(TcpSession *, int direction);
112 
113 void StreamTcpPruneSession(Flow *, uint8_t);
114 int StreamTcpReassembleDepthReached(Packet *p);
115 
116 void StreamTcpReassembleIncrMemuse(uint64_t size);
117 void StreamTcpReassembleDecrMemuse(uint64_t size);
118 int StreamTcpReassembleSetMemcap(uint64_t size);
119 uint64_t StreamTcpReassembleGetMemcap(void);
120 int StreamTcpReassembleCheckMemcap(uint64_t size);
121 uint64_t StreamTcpReassembleMemuseGlobalCounter(void);
122 
123 void StreamTcpDisableAppLayer(Flow *f);
124 int StreamTcpAppLayerIsDisabled(Flow *f);
125 
126 #ifdef UNITTESTS
127 int StreamTcpCheckStreamContents(uint8_t *, uint16_t , TcpStream *);
128 #endif
129 
130 bool StreamReassembleRawHasDataReady(TcpSession *ssn, Packet *p);
131 void StreamTcpReassemblySetMinInspectDepth(TcpSession *ssn, int direction, uint32_t depth);
132 
STREAM_LASTACK_GT_BASESEQ(const TcpStream * stream)133 static inline bool STREAM_LASTACK_GT_BASESEQ(const TcpStream *stream)
134 {
135     /* last ack not yet initialized */
136     if (STREAM_BASE_OFFSET(stream) == 0 && stream->last_ack == 0)
137         return false;
138     if (SEQ_GT(stream->last_ack, stream->base_seq))
139         return true;
140     return false;
141 }
142 
143 uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream);
144 
145 #endif /* __STREAM_TCP_REASSEMBLE_H__ */
146 
147