📄 snort_stream5_tcp.c
字号:
/* $Id$ *//** * @file spp_stream5.c * @author Martin Roesch <roesch@sourcefire.com> * @author Steven Sturges <ssturges@sourcefire.com> * *//* * TODOs: * - midstream ssn pickup (done, SAS 10/14/2005) * - syn flood protection (done, SAS 9/27/2005) * * - review policy anomaly detection * + URG pointer (TODO) * + data on SYN (done, SAS 10/12/2005) * + data on FIN (done, SAS 10/12/2005) * + data after FIN (done, SAS 10/13/2005) * + window scaling/window size max (done, SAS 10/13/2005) * + PAWs, TCP Timestamps (done, SAS 10/12/2005) * * - session shutdown/Reset handling * - flush policy for Window/Consumed * - limit on number of overlapping packets? *//* * Copyright (C) 2004-2005 Sourcefire, Inc. */#include "debug.h"#include "detect.h"#include "plugbase.h"#include "mstring.h"#include "sfxhash.h"#include "util.h"#include "sflsq.h"#include "bounds.h"#include "generators.h"#include "event_queue.h"#include "snort.h"#include "decode.h"#include "snort_packet_header.h"#include "log.h"#include "stream5_common.h"#include "stream_api.h"#include "snort_stream5_session.h"#include "stream_ignore.h"#include "inline.h"#include "profiler.h"#ifdef PERF_PROFILINGPreprocStats s5TcpPerfStats;PreprocStats s5TcpNewSessPerfStats;PreprocStats s5TcpStatePerfStats;PreprocStats s5TcpDataPerfStats;PreprocStats s5TcpInsertPerfStats;PreprocStats s5TcpFlushPerfStats;PreprocStats s5TcpBuildPacketPerfStats;PreprocStats s5TcpProcessRebuiltPerfStats;#endif/* M A C R O S **************************************************/#ifndef DEBUG#ifndef INLINE#define INLINE inline#endif#else#ifdef INLINE#undef INLINE#endif#define INLINE#endif /* DEBUG *//* TCP flags */#define TH_FIN 0x01#define TH_SYN 0x02#define TH_RST 0x04#define TH_PUSH 0x08#define TH_ACK 0x10#define TH_URG 0x20#define TH_ECE 0x40#define TH_CWR 0x80#define TH_NORESERVED (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG)/* TCP states */#define TCP_STATE_NONE 0#define TCP_STATE_LISTEN 1#define TCP_STATE_SYN_RCVD 2#define TCP_STATE_SYN_SENT 3#define TCP_STATE_ESTABLISHED 4#define TCP_STATE_CLOSE_WAIT 5#define TCP_STATE_LAST_ACK 6#define TCP_STATE_FIN_WAIT_1 7#define TCP_STATE_CLOSING 8#define TCP_STATE_FIN_WAIT_2 9#define TCP_STATE_TIME_WAIT 10#define TCP_STATE_CLOSED 11/* Macros to deal with sequence numbers - p810 TCP Illustrated vol 2 */#define SEQ_LT(a,b) ((int)((a) - (b)) < 0)#define SEQ_LEQ(a,b) ((int)((a) - (b)) <= 0)#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)#define SEQ_GEQ(a,b) ((int)((a) - (b)) >= 0)#define SEQ_EQ(a,b) ((int)((a) - (b)) == 0)#define PAWS_WINDOW 60#define PAWS_24DAYS 2073600 /* 24 days in seconds *//* for state transition queuing */#define CHK_SEQ 0#define NO_CHK_SEQ 1#define S5_UNALIGNED 0#define S5_ALIGNED 1/* actions */#define ACTION_NOTHING 0x00000000#define ACTION_FLUSH_SENDER_STREAM 0x00000001#define ACTION_FLUSH_RECEIVER_STREAM 0x00000002#define ACTION_DROP_SESSION 0x00000004#define ACTION_ACK_SENDER_DATA 0x00000008#define ACTION_ACK_RECEIVER_DATA 0x00000010#define ACTION_DATA_ON_SYN 0x00000020#define ACTION_SET_SSN 0x00000040#define ACTION_COMPLETE_TWH 0x00000080#define ACTION_RST 0x00000100#define ACTION_BAD_SEQ 0x00000200#define ACTION_BAD_PKT 0x00000400#define TF_NONE 0x00000000#define TF_WSCALE 0x00000001#define TF_TSTAMP 0x00000002#define TF_TSTAMP_ZERO 0x00000004#define TF_MSS 0x00000008#define TF_FORCE_FLUSH 0x10000000#define TF_MISSING_PKT 0x20000000#define TF_ALL 0xFFFFFFFF#define STREAM_INSERT_OK 0#define STREAM_INSERT_ANOMALY 1#define STREAM_INSERT_TIMEOUT 2#define STREAM_INSERT_FAILED 3#define S5_DEFAULT_TCP_PACKET_MEMCAP 8388608 /* 8MB */#define REASSEMBLY_POLICY_FIRST 1#define REASSEMBLY_POLICY_LINUX 2#define REASSEMBLY_POLICY_BSD 3#define REASSEMBLY_POLICY_OLD_LINUX 4#define REASSEMBLY_POLICY_LAST 5#define REASSEMBLY_POLICY_WINDOWS 6#define REASSEMBLY_POLICY_SOLARIS 7#define REASSEMBLY_POLICY_HPUX 8#define REASSEMBLY_POLICY_IRIX 9#define REASSEMBLY_POLICY_MACOS 10#define STREAM_MAX_PACKET (IP_MAXPACKET - (ETHERNET_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN))#define STREAM5_DEBUG_WRAP(x)//#define STREAM5_DEBUG_WRAP(x) DEBUG_WRAP(x)/* D A T A S T R U C T U R E S ***********************************/typedef struct _TcpDataBlock{ u_int32_t sip; u_int32_t dip; u_int32_t seq; u_int32_t ack; u_int16_t win; u_int32_t end_seq; u_int32_t ts;} TcpDataBlock;typedef struct _StateMgr{ u_int8_t state; u_int8_t state_queue; u_int8_t expected_flags; u_int32_t transition_seq; u_int32_t stq_get_seq;} StateMgr;#define RAND_FLUSH_POINTS 64typedef struct _FlushMgr{ u_int32_t flush_pt; u_int32_t flush_policy; u_int32_t flush_range; u_int32_t flush_base; /* Set as value - range/2 */ /* flush_pt is split evently on either side of flush_value, within * the flush_range. flush_pt can be from: * (flush_value - flush_range/2) to (flush_value + flush_range/2) * * For example: * flush_value = 192 * flush_range = 128 * flush_pt will vary from 128 to 256 */#ifndef DYNAMIC_RANDOM_FLUSH_POINTS u_int32_t flush_pt_index; u_int32_t flush_pts[RAND_FLUSH_POINTS];#endif} FlushMgr;typedef struct _FlushPolicy{ FlushMgr client; FlushMgr server; //SF_LIST *dynamic_policy;} FlushPolicy;typedef struct _CustomFlushPolicy{ FlushMgr client; FlushMgr server; IpAddrSet *bound_addrs;} CustomFlushPolicy;typedef struct _StreamSegment{ SnortPktHeader pkth; u_int8_t *pkt; u_int8_t *pktOrig; u_int32_t cksum; u_int8_t *data; u_int16_t size; u_int32_t seq; u_int8_t *dptr; u_int16_t caplen; u_int16_t urg_offset; u_int8_t buffered; u_int8_t blocked; struct _StreamSegment *prev; struct _StreamSegment *next;} StreamSegment;typedef struct _StreamTracker{ u_int32_t flags; /* bitmap flags */ StateMgr s_mgr; /* state tracking goodies */ FlushMgr flush_mgr; /* please flush twice, it's a long way to * the bitbucket... */ u_int32_t isn; /* initial sequence number */ u_int8_t ttl; /* base ttl at session startup */ u_int32_t ts_last_pkt; /* last packet timestamp we got */ /* tcp option handling */ u_int32_t ts_last; /* last timestamp (for PAWS) */ u_int16_t wscale; /* window scale setting */ u_int16_t mss; /* max segment size */ /* Local in the context of these variables means the local part * of the connection. For example, if this particular StreamTracker * was tracking the client side of a connection, the l_unackd value * would represent the client side of the connection's last unacked * sequence number */ u_int32_t l_unackd; /* local unack'd seq number */ u_int32_t l_nxt_seq; /* local next expected sequence */ u_int16_t l_window; /* local receive window */ u_int32_t r_nxt_ack; /* next expected ack from remote side */ u_int32_t r_win_base; /* remote side window base sequence number * (i.e. the last ack we got) */ u_int32_t gap_seq; /* sequence of next packet after a gap */ StreamSegment *seglist; StreamSegment *seglist_tail; u_int32_t seglist_base_seq; u_int32_t seg_count; u_int32_t seg_bytes_total; u_int32_t seg_bytes_logical; u_int32_t total_bytes_queued; u_int32_t total_segs_queued; u_int32_t overlap_count; Stream5AlertInfo alerts[MAX_SESSION_ALERTS]; int alert_count;} StreamTracker;#define MAX_PORTS 65536typedef struct _Stream5TcpPolicy{ u_int16_t policy; u_int16_t reassembly_policy; u_int32_t session_timeout; u_int8_t min_ttl; u_int32_t max_window; u_int32_t overlap_limit; u_int32_t hs_timeout; u_int16_t flags; IpAddrSet *bound_addrs; FlushPolicy flush_policy[MAX_PORTS];} Stream5TcpPolicy;typedef struct _TcpSession{ Stream5LWSession *lwSsn; StreamTracker client; StreamTracker server; u_int32_t client_ip; u_int16_t client_port; u_int32_t server_ip; u_int16_t server_port; struct timeval ssn_time; //u_int8_t c_ttl; //u_int8_t s_ttl; u_int32_t expire_time; Stream5TcpPolicy *policy;} TcpSession;int default_ports[] ={ 21, 23, 25, 42, 53, 80, 110, 111, 135, 136, 137, 139, 143, 445, 513, 1433, 1521, 3306#ifdef DEBUG , 12345#endif};static FlushPolicy ignore_flush_policy[MAX_PORTS];/* P R O T O T Y P E S ********************************************/static void Stream5ParseTcpArgs(u_char *, Stream5TcpPolicy *);static void Stream5PrintTcpConfig(Stream5TcpPolicy *);static void Stream5InitPacket();static INLINE void SetupTcpDataBlock(TcpDataBlock *, Packet *);static int ProcessTcp(Stream5LWSession *, Packet *, TcpDataBlock *, Stream5TcpPolicy *);static INLINE void QueueState(u_int8_t, StreamTracker*, u_int8_t, u_int32_t, u_int8_t);static INLINE int EvalStateQueue(StreamTracker *, u_int8_t, u_int32_t);static int CheckFlushPolicy(TcpSession *, StreamTracker *, StreamTracker *, TcpDataBlock *, Packet *);static void Stream5SeglistAddNode(StreamTracker *, StreamSegment *, StreamSegment *);static int Stream5SeglistDeleteNode(StreamTracker *, StreamSegment *);static int AddStreamNode(StreamTracker *st, Packet *p, Stream5TcpPolicy *s5TcpPolicy, int16_t len, u_int32_t slide, u_int32_t trunc, u_int32_t seq, StreamSegment *left, StreamSegment **retSeg);static u_int32_t Stream5GetWscale(Packet *, u_int16_t *);static u_int32_t Stream5GetMss(Packet *, u_int16_t *);static u_int32_t Stream5GetTcpTimestamp(Packet *, u_int32_t *);static int FlushStream(StreamTracker *st, Packet *p, u_int8_t *flushbuf, int size);void TcpSessionCleanup(Stream5LWSession *ssn);/* G L O B A L S **************************************************/static Stream5SessionCache *tcp_lws_cache;static MemPool tcp_session_mempool;static Packet *s5_pkt = NULL;static int s5_mem_in_use = 0;static Stream5TcpPolicy **tcpPolicyList = NULL; /* List of Policies configured */static u_int8_t numTcpPolicies = 0;static char midstream_allowed = 0;/* enum for policy names */static char *reassembly_policy_names[] = { "no policy!", "FIRST", "LINUX", "BSD", "OLD LINUX", "LAST", "WINDOWS", "SOLARIS", "HPUX", "IRIX", "MACOS"};#ifdef DEBUGstatic char *state_names[] = { "NONE", "LISTEN", "SYN_RCVD", "SYN_SENT", "ESTABLISHED", "CLOSE_WAIT", "LAST_ACK", "FIN_WAIT_1", "CLOSING", "FIN_WAIT_2",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -