From: Russ Combs Date: Mon, 1 Dec 2014 18:51:55 +0000 (-0500) Subject: convert add session alert and check session alerted functionality into session virtua... X-Git-Tag: 3.0.0-233~1146^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38cd5ceccd5ae0657a87e3572130a5a6c75f677d;p=thirdparty%2Fsnort3.git convert add session alert and check session alerted functionality into session virtuals for ip and tcp --- diff --git a/src/detection/fpdetect.cc b/src/detection/fpdetect.cc index a2ed460f7..900272399 100644 --- a/src/detection/fpdetect.cc +++ b/src/detection/fpdetect.cc @@ -851,7 +851,6 @@ static inline int fpFinalSelectEvent(OTNX_MATCH_DATA *o, Packet *p) ** 1 if flagged ** */ -// FIXIT-H this should include frags now that they are in session static inline int fpAddSessionAlert(Packet *p, OptTreeNode *otn) { if ( !p->flow ) @@ -882,7 +881,6 @@ static inline int fpAddSessionAlert(Packet *p, OptTreeNode *otn) ** 1 if alert previously generated ** */ -// FIXIT-H this should include frags now that they are in session static inline int fpSessionAlerted(Packet *p, OptTreeNode *otn) { SigInfo *si = &otn->sigInfo; @@ -1080,7 +1078,7 @@ static inline int fpEvalHeaderSW(PORT_GROUP *port_group, Packet *p, ** payload, in case any of the rules have the ** 'rawbytes' option. */ - // FIXIT-H alt buf and file data should be obtained from + // FIXIT-M alt buf and file data should be obtained from // inspector gadget as an extension of above so = port_group->pgPms[PM_TYPE__CONTENT]; diff --git a/src/flow/session.h b/src/flow/session.h index c737a2503..71245c8c4 100644 --- a/src/flow/session.h +++ b/src/flow/session.h @@ -36,10 +36,14 @@ public: virtual bool setup(Packet*) { return true; }; virtual void update_direction(char /*dir*/, const sfip_t*, uint16_t /*port*/) { }; virtual int process(Packet*) { return 0; }; + virtual void restart(Packet*) { }; virtual void clear() = 0; virtual void cleanup() { clear(); }; + virtual bool add_alert(Packet*, uint32_t /*gid*/, uint32_t /*sid*/) { return false; }; + virtual bool check_alerted(Packet*, uint32_t /*gid*/, uint32_t /*sid*/) { return false; }; + protected: Session(Flow* f) { flow = f; }; diff --git a/src/stream/ip/ip_defrag.cc b/src/stream/ip/ip_defrag.cc index 8b91138e2..ec1c77a11 100644 --- a/src/stream/ip/ip_defrag.cc +++ b/src/stream/ip/ip_defrag.cc @@ -2213,6 +2213,7 @@ int Defrag::new_tracker(Packet *p, FragTracker* ft) ft->frag_pkts = 0; ft->frag_time.tv_sec = p->pkth->ts.tv_sec; ft->frag_time.tv_usec = p->pkth->ts.tv_usec; + ft->alert_count = 0; ft->ip_options_len = 0; ft->ip_options_data = NULL; ft->copied_ip_options_len = 0; diff --git a/src/stream/ip/ip_session.cc b/src/stream/ip/ip_session.cc index d8e91a759..ef96d1746 100644 --- a/src/stream/ip/ip_session.cc +++ b/src/stream/ip/ip_session.cc @@ -182,3 +182,37 @@ int IpSession::process(Packet* p) return 0; } +bool IpSession::add_alert(Packet*, uint32_t gid, uint32_t sid) +{ + FragTracker* ft = &tracker; + + /* Only track a certain number of alerts per session */ + if ( ft->alert_count >= MAX_FRAG_ALERTS ) + return false; + + ft->alert_gid[ft->alert_count] = gid; + ft->alert_sid[ft->alert_count] = sid; + ft->alert_count++; + + return true; +} + +bool IpSession::check_alerted(Packet* p, uint32_t gid, uint32_t sid) +{ + FragTracker* ft = &tracker; + + for ( unsigned i = 0; i < ft->alert_count; i++ ) + { + /* If this is a rebuilt packet and we've seen this alert before, return + * that we have previously alerted on a non-rebuilt packet. + */ + if ( (p->packet_flags & PKT_REBUILT_FRAG) + && ft->alert_gid[i] == gid && ft->alert_sid[i] == sid ) + { + return true; + } + } + + return false; +} + diff --git a/src/stream/ip/ip_session.h b/src/stream/ip/ip_session.h index a98d63394..00efbb4ac 100644 --- a/src/stream/ip/ip_session.h +++ b/src/stream/ip/ip_session.h @@ -29,6 +29,9 @@ struct Fragment; struct FragEngine; +/* Only track a certain number of alerts per session */ +#define MAX_FRAG_ALERTS 8 + /* tracker for a fragmented packet set */ struct FragTracker { @@ -54,6 +57,10 @@ struct FragTracker Fragment *fraglist_tail; /* tail ptr for easy appending */ int fraglist_count; /* handy dandy counter */ + uint32_t alert_gid[MAX_FRAG_ALERTS]; /* flag alerts seen in a frag list */ + uint32_t alert_sid[MAX_FRAG_ALERTS]; /* flag alerts seen in a frag list */ + uint8_t alert_count; /* count alerts seen in a frag list */ + uint8_t ip_options_len; /* length of ip options for this set of frags */ uint8_t *ip_options_data; /* ip options from offset 0 packet */ uint8_t copied_ip_options_len; /* length of 'copied' ip options */ @@ -78,6 +85,9 @@ public: int process(Packet*) override; void clear() override; + bool add_alert(Packet*, uint32_t gid, uint32_t sid) override; + bool check_alerted(Packet*, uint32_t gid, uint32_t sid) override; + public: FragTracker tracker; }; diff --git a/src/stream/stream_api.cc b/src/stream/stream_api.cc index fe01fa217..bdbd6dcf6 100644 --- a/src/stream/stream_api.cc +++ b/src/stream/stream_api.cc @@ -780,33 +780,24 @@ int Stream::response_flush_stream(Packet *p) return 0; } -int Stream::add_session_alert( +// return true if added +bool Stream::add_session_alert( Flow *flow, Packet *p, uint32_t gid, uint32_t sid) { if ( !flow ) - return 0; - - /* Don't need to do this for other protos because they don't - do any reassembly. */ - if ( p->type() != PktType::TCP ) - return 0; + return false; - return Stream5AddSessionAlertTcp(flow, p, gid, sid); + return flow->session->add_alert(p, gid, sid); } -/* return non-zero if gid/sid have already been seen */ -int Stream::check_session_alerted( +// return true if gid/sid have already been seen +bool Stream::check_session_alerted( Flow *flow, Packet *p, uint32_t gid, uint32_t sid) { if ( !flow ) - return 0; - - /* Don't need to do this for other protos because they don't - do any reassembly. */ - if ( p->type() != PktType::TCP ) - return 0; + return false; - return Stream5CheckSessionAlertTcp(flow, p, gid, sid); + return flow->session->check_alerted(p, gid, sid); } int Stream::update_session_alert( diff --git a/src/stream/stream_api.h b/src/stream/stream_api.h index fde7277b9..252e71417 100644 --- a/src/stream/stream_api.h +++ b/src/stream/stream_api.h @@ -148,17 +148,13 @@ public: */ static int traverse_stream_segments(Packet*, StreamSegmentIterator, void* userdata); // PKT - /* Add session alert + /* Add session alert - true if added */ - static int add_session_alert(Flow*, Packet*, uint32_t gid, uint32_t sid); + static bool add_session_alert(Flow*, Packet*, uint32_t gid, uint32_t sid); - /* Check session alert - * - * Returns - * 0 if not previously alerted - * !0 if previously alerted + /* Check session alert - true if previously alerted */ - static int check_session_alerted(Flow*, Packet *p, uint32_t gid, uint32_t sid); + static bool check_session_alerted(Flow*, Packet *p, uint32_t gid, uint32_t sid); /* Set Extra Data Logging * diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index c93f6fb38..900ca1813 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -6317,7 +6317,7 @@ int Stream5AddSessionAlertTcp( st->alert_count++; - return 0; + return 1; } int Stream5CheckSessionAlertTcp(Flow *lwssn, Packet *p, uint32_t gid, uint32_t sid) @@ -6810,6 +6810,16 @@ midstream_pickup_allowed: return 0; } +bool TcpSession::add_alert(Packet* p, uint32_t gid, uint32_t sid) +{ + return Stream5AddSessionAlertTcp(p->flow, p, gid, sid) != 0; +} + +bool TcpSession::check_alerted(Packet* p, uint32_t gid, uint32_t sid) +{ + return Stream5CheckSessionAlertTcp(p->flow, p, gid, sid) != 0; +} + //------------------------------------------------------------------------- // tcp module stuff //------------------------------------------------------------------------- diff --git a/src/stream/tcp/tcp_session.h b/src/stream/tcp/tcp_session.h index 1a5d56fe6..7ba01d39e 100644 --- a/src/stream/tcp/tcp_session.h +++ b/src/stream/tcp/tcp_session.h @@ -206,6 +206,9 @@ public: void reset(); void restart(Packet*) override; + bool add_alert(Packet*, uint32_t gid, uint32_t sid) override; + bool check_alerted(Packet*, uint32_t gid, uint32_t sid) override; + public: StreamTracker client; StreamTracker server;