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 __STREAM_TCP_PRIVATE_H__ 25 #define __STREAM_TCP_PRIVATE_H__ 26 27 #include "tree.h" 28 #include "decode.h" 29 #include "util-pool.h" 30 #include "util-pool-thread.h" 31 #include "util-streaming-buffer.h" 32 33 #define STREAMTCP_QUEUE_FLAG_TS 0x01 34 #define STREAMTCP_QUEUE_FLAG_WS 0x02 35 #define STREAMTCP_QUEUE_FLAG_SACK 0x04 36 37 /** currently only SYN/ACK */ 38 typedef struct TcpStateQueue_ { 39 uint8_t flags; 40 uint8_t wscale; 41 uint16_t win; 42 uint32_t seq; 43 uint32_t ack; 44 uint32_t ts; 45 uint32_t pkt_ts; 46 struct TcpStateQueue_ *next; 47 } TcpStateQueue; 48 49 typedef struct StreamTcpSackRecord { 50 uint32_t le; /**< left edge, host order */ 51 uint32_t re; /**< right edge, host order */ 52 RB_ENTRY(StreamTcpSackRecord) rb; 53 } StreamTcpSackRecord; 54 55 int TcpSackCompare(struct StreamTcpSackRecord *a, struct StreamTcpSackRecord *b); 56 57 /* red-black tree prototype for SACK records */ 58 RB_HEAD(TCPSACK, StreamTcpSackRecord); 59 RB_PROTOTYPE(TCPSACK, StreamTcpSackRecord, rb, TcpSackCompare); 60 61 typedef struct TcpSegment { 62 PoolThreadReserved res; 63 uint16_t payload_len; /**< actual size of the payload */ 64 uint32_t seq; 65 RB_ENTRY(TcpSegment) __attribute__((__packed__)) rb; 66 StreamingBufferSegment sbseg; 67 } __attribute__((__packed__)) TcpSegment; 68 69 /** \brief compare function for the Segment tree 70 * 71 * Main sort point is the sequence number. When sequence numbers 72 * are equal compare payload_len as well. This way the tree is 73 * sorted by seq, and in case of duplicate seqs we are sorted 74 * small to large. 75 */ 76 int TcpSegmentCompare(struct TcpSegment *a, struct TcpSegment *b); 77 78 /* red-black tree prototype for TcpSegment */ 79 RB_HEAD(TCPSEG, TcpSegment); 80 RB_PROTOTYPE(TCPSEG, TcpSegment, rb, TcpSegmentCompare); 81 82 #define TCP_SEG_LEN(seg) (seg)->payload_len 83 #define TCP_SEG_OFFSET(seg) (seg)->sbseg.stream_offset 84 85 #define SEG_SEQ_RIGHT_EDGE(seg) ((seg)->seq + TCP_SEG_LEN((seg))) 86 87 /* get right edge of sequence space of seen segments. 88 * Only use if STREAM_HAS_SEEN_DATA is true. */ 89 #define STREAM_SEQ_RIGHT_EDGE(stream) (stream)->segs_right_edge 90 #define STREAM_RIGHT_EDGE(stream) (STREAM_BASE_OFFSET((stream)) + (STREAM_SEQ_RIGHT_EDGE((stream)) - (stream)->base_seq)) 91 /* return true if we have seen data segments. */ 92 #define STREAM_HAS_SEEN_DATA(stream) (!RB_EMPTY(&(stream)->sb.sbb_tree) || (stream)->sb.stream_offset || (stream)->sb.buf_offset) 93 94 typedef struct TcpStream_ { 95 uint16_t flags:12; /**< Flag specific to the stream e.g. Timestamp */ 96 /* coccinelle: TcpStream:flags:STREAMTCP_STREAM_FLAG_ */ 97 uint16_t wscale:4; /**< wscale setting in this direction, 4 bits as max val is 15 */ 98 uint8_t os_policy; /**< target based OS policy used for reassembly and handling packets*/ 99 uint8_t tcp_flags; /**< TCP flags seen */ 100 101 uint32_t isn; /**< initial sequence number */ 102 uint32_t next_seq; /**< next expected sequence number */ 103 uint32_t last_ack; /**< last ack'd sequence number in this stream */ 104 uint32_t next_win; /**< next max seq within window */ 105 uint32_t window; /**< current window setting, after wscale is applied */ 106 107 uint32_t last_ts; /**< Time stamp (TSVAL) of the last seen packet for this stream*/ 108 uint32_t last_pkt_ts; /**< Time of last seen packet for this stream (needed for PAWS update) 109 This will be used to validate the last_ts, when connection has been idle for 110 longer time.(RFC 1323)*/ 111 /* reassembly */ 112 uint32_t base_seq; /**< seq where we are left with reassebly. Matches STREAM_BASE_OFFSET below. */ 113 114 uint32_t app_progress_rel; /**< app-layer progress relative to STREAM_BASE_OFFSET */ 115 uint32_t raw_progress_rel; /**< raw reassembly progress relative to STREAM_BASE_OFFSET */ 116 uint32_t log_progress_rel; /**< streaming logger progress relative to STREAM_BASE_OFFSET */ 117 118 uint32_t min_inspect_depth; /**< min inspect size set by the app layer, to make sure enough data 119 * remains available for inspection together with app layer buffers */ 120 uint32_t data_required; /**< data required from STREAM_APP_PROGRESS before calling app-layer again */ 121 122 StreamingBuffer sb; 123 struct TCPSEG seg_tree; /**< red black tree of TCP segments. Data is stored in TcpStream::sb */ 124 uint32_t segs_right_edge; 125 126 uint32_t sack_size; /**< combined size of the SACK ranges currently in our tree. Updated 127 * at INSERT/REMOVE time. */ 128 struct TCPSACK sack_tree; /**< red back tree of TCP SACK records. */ 129 } TcpStream; 130 131 #define STREAM_BASE_OFFSET(stream) ((stream)->sb.stream_offset) 132 #define STREAM_APP_PROGRESS(stream) (STREAM_BASE_OFFSET((stream)) + (stream)->app_progress_rel) 133 #define STREAM_RAW_PROGRESS(stream) (STREAM_BASE_OFFSET((stream)) + (stream)->raw_progress_rel) 134 #define STREAM_LOG_PROGRESS(stream) (STREAM_BASE_OFFSET((stream)) + (stream)->log_progress_rel) 135 136 /* from /usr/include/netinet/tcp.h */ 137 enum TcpState 138 { 139 TCP_NONE, 140 TCP_LISTEN, 141 TCP_SYN_SENT, 142 TCP_SYN_RECV, 143 TCP_ESTABLISHED, 144 TCP_FIN_WAIT1, 145 TCP_FIN_WAIT2, 146 TCP_TIME_WAIT, 147 TCP_LAST_ACK, 148 TCP_CLOSE_WAIT, 149 TCP_CLOSING, 150 TCP_CLOSED, 151 }; 152 153 /* 154 * Per SESSION flags 155 */ 156 157 /** Flag for mid stream session */ 158 #define STREAMTCP_FLAG_MIDSTREAM 0x0001 159 /** Flag for mid stream established session */ 160 #define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED 0x0002 161 /** Flag for mid session when syn/ack is received */ 162 #define STREAMTCP_FLAG_MIDSTREAM_SYNACK 0x0004 163 /** Flag for TCP Timestamp option */ 164 #define STREAMTCP_FLAG_TIMESTAMP 0x0008 165 /** Server supports wscale (even though it can be 0) */ 166 #define STREAMTCP_FLAG_SERVER_WSCALE 0x0010 167 /** Closed by RST */ 168 #define STREAMTCP_FLAG_CLOSED_BY_RST 0x0020 169 /** Flag to indicate that the session is handling asynchronous stream.*/ 170 #define STREAMTCP_FLAG_ASYNC 0x0040 171 /** Flag to indicate we're dealing with 4WHS: SYN, SYN, SYN/ACK, ACK 172 * (http://www.breakingpointsystems.com/community/blog/tcp-portals-the-three-way-handshake-is-a-lie) */ 173 #define STREAMTCP_FLAG_4WHS 0x0080 174 /** Flag to indicate that this session is possible trying to evade the detection 175 * (http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make.html) */ 176 #define STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT 0x0100 177 /** Flag to indicate the client (SYN pkt) permits SACK */ 178 #define STREAMTCP_FLAG_CLIENT_SACKOK 0x0200 179 /** Flag to indicate both sides of the session permit SACK (SYN + SYN/ACK) */ 180 #define STREAMTCP_FLAG_SACKOK 0x0400 181 // vacancy 182 /** 3WHS confirmed by server -- if suri sees 3whs ACK but server doesn't (pkt 183 * is lost on the way to server), SYN/ACK is retransmitted. If server sends 184 * normal packet we assume 3whs to be completed. Only used for SYN/ACK resend 185 * event. */ 186 #define STREAMTCP_FLAG_3WHS_CONFIRMED 0x1000 187 /** App Layer tracking/reassembly is disabled */ 188 #define STREAMTCP_FLAG_APP_LAYER_DISABLED 0x2000 189 /** Stream can be bypass */ 190 #define STREAMTCP_FLAG_BYPASS 0x4000 191 /** SSN uses TCP Fast Open */ 192 #define STREAMTCP_FLAG_TCP_FAST_OPEN 0x8000 193 194 /* 195 * Per STREAM flags 196 */ 197 198 // bit 0 vacant 199 /** Flag to avoid stream reassembly/app layer inspection for the stream */ 200 #define STREAMTCP_STREAM_FLAG_NOREASSEMBLY BIT_U16(1) 201 /** we received a keep alive */ 202 #define STREAMTCP_STREAM_FLAG_KEEPALIVE BIT_U16(2) 203 /** Stream has reached it's reassembly depth, all further packets are ignored */ 204 #define STREAMTCP_STREAM_FLAG_DEPTH_REACHED BIT_U16(3) 205 /** Trigger reassembly next time we need 'raw' */ 206 #define STREAMTCP_STREAM_FLAG_TRIGGER_RAW BIT_U16(4) 207 /** Stream supports TIMESTAMP -- used to set ssn STREAMTCP_FLAG_TIMESTAMP 208 * flag. */ 209 #define STREAMTCP_STREAM_FLAG_TIMESTAMP BIT_U16(5) 210 /** Flag to indicate the zero value of timestamp */ 211 #define STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP BIT_U16(6) 212 /** App proto detection completed */ 213 #define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED BIT_U16(7) 214 /** App proto detection skipped */ 215 #define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED BIT_U16(8) 216 /** Raw reassembly disabled for new segments */ 217 #define STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED BIT_U16(9) 218 /** Raw reassembly disabled completely */ 219 #define STREAMTCP_STREAM_FLAG_DISABLE_RAW BIT_U16(10) 220 221 #define STREAMTCP_STREAM_FLAG_RST_RECV BIT_U16(11) 222 223 /** NOTE: flags field is 12 bits */ 224 225 226 227 228 #define PAWS_24DAYS 2073600 /**< 24 days in seconds */ 229 230 #define PKT_IS_IN_RIGHT_DIR(ssn, p) ((ssn)->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK ? \ 231 PKT_IS_TOSERVER(p) ? (p)->flowflags &= ~FLOW_PKT_TOSERVER \ 232 (p)->flowflags |= FLOW_PKT_TOCLIENT : (p)->flowflags &= ~FLOW_PKT_TOCLIENT \ 233 (p)->flowflags |= FLOW_PKT_TOSERVER : 0) 234 235 /* Macro's for comparing Sequence numbers 236 * Page 810 from TCP/IP Illustrated, Volume 2. */ 237 #define SEQ_EQ(a,b) ((int32_t)((a) - (b)) == 0) 238 #define SEQ_LT(a,b) ((int32_t)((a) - (b)) < 0) 239 #define SEQ_LEQ(a,b) ((int32_t)((a) - (b)) <= 0) 240 #define SEQ_GT(a,b) ((int32_t)((a) - (b)) > 0) 241 #define SEQ_GEQ(a,b) ((int32_t)((a) - (b)) >= 0) 242 243 #define STREAMTCP_SET_RA_BASE_SEQ(stream, seq) { \ 244 do { \ 245 (stream)->base_seq = (seq) + 1; \ 246 } while(0); \ 247 } 248 249 #define StreamTcpSetEvent(p, e) { \ 250 if ((p)->flags & PKT_STREAM_NO_EVENTS) { \ 251 SCLogDebug("not setting event %d on pkt %p (%"PRIu64"), " \ 252 "stream in known bad condition", (e), p, (p)->pcap_cnt); \ 253 } else { \ 254 SCLogDebug("setting event %d on pkt %p (%"PRIu64")", \ 255 (e), p, (p)->pcap_cnt); \ 256 ENGINE_SET_EVENT((p), (e)); \ 257 } \ 258 } 259 260 typedef struct TcpSession_ { 261 PoolThreadReserved res; 262 uint8_t state:4; /**< tcp state from state enum */ 263 uint8_t pstate:4; /**< previous state */ 264 uint8_t queue_len; /**< length of queue list below */ 265 int8_t data_first_seen_dir; 266 /** track all the tcp flags we've seen */ 267 uint8_t tcp_packet_flags; 268 /* coccinelle: TcpSession:flags:STREAMTCP_FLAG */ 269 uint16_t flags; 270 uint32_t reassembly_depth; /**< reassembly depth for the stream */ 271 TcpStream server; 272 TcpStream client; 273 TcpStateQueue *queue; /**< list of SYN/ACK candidates */ 274 } TcpSession; 275 276 #define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream) \ 277 ((stream)->flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) 278 #define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream) \ 279 ((stream)->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) 280 #define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream) \ 281 ((stream)->flags &= ~STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED); 282 #define StreamTcpDisableAppLayerReassembly(ssn) do { \ 283 SCLogDebug("setting STREAMTCP_FLAG_APP_LAYER_DISABLED on ssn %p", ssn); \ 284 ((ssn)->flags |= STREAMTCP_FLAG_APP_LAYER_DISABLED); \ 285 } while (0); 286 287 #endif /* __STREAM_TCP_PRIVATE_H__ */ 288