You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/src/stream-tcp.h

216 lines
7.2 KiB
C

/* Copyright (C) 2007-2010 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Victor Julien <victor@inliniac.net>
* \author Gurvinder Singh <gurvindersinghdahiya@gmail.com>
*/
#ifndef __STREAM_TCP_H__
#define __STREAM_TCP_H__
#include "stream-tcp-private.h"
#define COUNTER_STREAMTCP_STREAMS 1
#include "app-layer-detect-proto.h"
#include "util-mpm.h"
#include "stream.h"
#include "stream-tcp-reassemble.h"
#define STREAM_VERBOSE FALSE
/* Flag to indicate that the checksum validation for the stream engine
has been enabled */
#define STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION 0x01
/*global flow data*/
typedef struct TcpStreamCnf_ {
/** stream tracking
*
* max stream mem usage
*/
uint64_t memcap;
uint64_t reassembly_memcap; /**< max memory usage for stream reassembly */
uint32_t ssn_init_flags; /**< new ssn flags will be initialized to this */
uint8_t segment_init_flags; /**< new seg flags will be initialized to this */
uint32_t prealloc_sessions; /**< ssns to prealloc per stream thread */
int midstream;
int async_oneside;
uint32_t reassembly_depth; /**< Depth until when we reassemble the stream */
uint16_t reassembly_toserver_chunk_size;
uint16_t reassembly_toclient_chunk_size;
int check_overlap_different_data;
/** reassembly -- inline mode
*
* sliding window size for raw stream reassembly
*/
uint32_t reassembly_inline_window;
uint8_t flags;
uint8_t max_synack_queued;
} TcpStreamCnf;
typedef struct StreamTcpThread_ {
int ssn_pool_id;
uint64_t pkts;
/** queue for pseudo packet(s) that were created in the stream
* process and need further handling. Currently only used when
* receiving (valid) RST packets */
PacketQueue pseudo_queue;
uint16_t counter_tcp_sessions;
/** sessions not picked up because memcap was reached */
uint16_t counter_tcp_ssn_memcap;
/** pseudo packets processed */
uint16_t counter_tcp_pseudo;
/** packets rejected because their csum is invalid */
uint16_t counter_tcp_invalid_checksum;
/** TCP packets with no associated flow */
uint16_t counter_tcp_no_flow;
/** sessions reused */
uint16_t counter_tcp_reused_ssn;
/** sessions reused */
uint16_t counter_tcp_memuse;
/** syn pkts */
uint16_t counter_tcp_syn;
/** syn/ack pkts */
uint16_t counter_tcp_synack;
/** rst pkts */
uint16_t counter_tcp_rst;
/** tcp reassembly thread data */
TcpReassemblyThreadCtx *ra_ctx;
} StreamTcpThread;
TcpStreamCnf stream_config;
void TmModuleStreamTcpRegister (void);
void StreamTcpInitConfig (char);
void StreamTcpFreeConfig(char);
void StreamTcpRegisterTests (void);
void StreamTcpSessionPktFree (Packet *);
void StreamTcpIncrMemuse(uint64_t);
void StreamTcpDecrMemuse(uint64_t);
int StreamTcpCheckMemcap(uint64_t);
Packet *StreamTcpPseudoSetup(Packet *, uint8_t *, uint32_t);
int StreamTcpSegmentForEach(const Packet *p, uint8_t flag,
StreamSegmentCallback CallbackFunc,
void *data);
void StreamTcpReassembleConfigEnableOverlapCheck(void);
/** ------- Inline functions: ------ */
/**
* \brief If we are on IPS mode, and got a drop action triggered from
* the IP only module, or from a reassembled msg and/or from an
* applayer detection, then drop the rest of the packets of the
* same stream and avoid inspecting it any further
* \param p pointer to the Packet to check
* \retval 1 if we must drop this stream
* \retval 0 if the stream still legal
*/
static inline int StreamTcpCheckFlowDrops(Packet *p)
{
/* If we are on IPS mode, and got a drop action triggered from
* the IP only module, or from a reassembled msg and/or from an
* applayer detection, then drop the rest of the packets of the
* same stream and avoid inspecting it any further */
if (EngineModeIsIPS() && (p->flow->flags & FLOW_ACTION_DROP))
return 1;
return 0;
}
/**
* \brief Function to flip the direction When we missed the SYN packet,
* SYN/ACK is considered as sent by server, but our engine flagged the
* packet as from client for the host whose packet is received first in
* the session.
*
* \param ssn TcpSession to whom this packet belongs
* \param p Packet whose flag has to be changed
*/
static inline void StreamTcpPacketSwitchDir(TcpSession *ssn, Packet *p)
{
SCLogDebug("ssn %p: switching pkt direction", ssn);
if (PKT_IS_TOSERVER(p)) {
p->flowflags &= ~FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_TOCLIENT;
} else {
p->flowflags &= ~FLOW_PKT_TOCLIENT;
p->flowflags |= FLOW_PKT_TOSERVER;
}
}
enum {
/* stream has no segments for forced reassembly, nor for detection */
STREAM_HAS_UNPROCESSED_SEGMENTS_NONE = 0,
/* stream seems to have segments that need to be forced reassembled */
STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY = 1,
/* stream has no segments for forced reassembly, but only segments that
* have been sent for detection, but are stuck in the detection queues */
STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION = 2,
};
static inline int StreamNeedsReassembly(TcpSession *ssn, int direction)
{
/* server tcp state */
if (direction) {
if (ssn->server.seg_list != NULL &&
(!(ssn->server.seg_list_tail->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) ||
!(ssn->server.seg_list_tail->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) ) {
return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY;
} else if (ssn->toclient_smsg_head != NULL) {
return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION;
} else {
return STREAM_HAS_UNPROCESSED_SEGMENTS_NONE;
}
} else {
if (ssn->client.seg_list != NULL &&
(!(ssn->client.seg_list_tail->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) ||
!(ssn->client.seg_list_tail->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) ) {
return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY;
} else if (ssn->toserver_smsg_head != NULL) {
return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION;
} else {
return STREAM_HAS_UNPROCESSED_SEGMENTS_NONE;
}
}
}
TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **);
TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data);
int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
PacketQueue *pq);
void StreamTcpSessionClear(void *ssnptr);
uint32_t StreamTcpGetStreamSize(TcpStream *stream);
#endif /* __STREAM_TCP_H__ */