diff --git a/NEWS b/NEWS index ac75844f31..ca564c43cd 100644 --- a/NEWS +++ b/NEWS @@ -167,6 +167,19 @@ New Functionality - Add parsing, analysis, and logging support for MQTT protocol v3.1/v3.1.1. +- Zeek now supports duration thresholding on connections, similarly to how it supports + byte and packet thresholds. + + - New events: + - ConnThreshold::duration_threshold_crossed + - conn_duration_threshold_crossed + + - New functions: + - ConnThreshold::set_duration_threshold + - ConnThreshold::delete_duration_threshold + - set_current_conn_duration_threshold + - get_current_conn_duration_threshold + Changed Functionality --------------------- diff --git a/doc b/doc index bf7b3d5ced..b044d24df7 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit bf7b3d5ced664a048f7ae9369cd7c6a17be43dbe +Subproject commit b044d24df7e40d1acff7f178610de4ce3c39adb0 diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index b0e7439438..12fcce29b2 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -96,6 +96,13 @@ type table_string_of_count: table[string] of count; ## directly and then remove this alias. type files_tag_set: set[Files::Tag]; +## A set of intervals. +## +## .. todo:: We need this type definition only for declaring builtin functions +## via ``bifcl``. We should extend ``bifcl`` to understand composite types +## directly and then remove this alias. +type interval_set: set[interval]; + ## A structure indicating a MIME type and strength of a match against ## file magic signatures. ## diff --git a/scripts/base/protocols/conn/thresholds.zeek b/scripts/base/protocols/conn/thresholds.zeek index d4ae21e1ab..c47f218d88 100644 --- a/scripts/base/protocols/conn/thresholds.zeek +++ b/scripts/base/protocols/conn/thresholds.zeek @@ -8,8 +8,9 @@ export { type Thresholds: record { orig_byte: set[count] &default=count_set(); ##< current originator byte thresholds we watch for resp_byte: set[count] &default=count_set(); ##< current responder byte thresholds we watch for - orig_packet: set[count] &default=count_set(); ##< corrent originator packet thresholds we watch for - resp_packet: set[count] &default=count_set(); ##< corrent responder packet thresholds we watch for + orig_packet: set[count] &default=count_set(); ##< current originator packet thresholds we watch for + resp_packet: set[count] &default=count_set(); ##< current responder packet thresholds we watch for + duration: set[interval] &default=interval_set(); ##< current duration thresholds we watch for }; ## Sets a byte threshold for connection sizes, adding it to potentially already existing thresholds. @@ -36,6 +37,16 @@ export { ## Returns: T on success, F on failure. global set_packets_threshold: function(c: connection, threshold: count, is_orig: bool): bool; + ## Sets a duration threshold for a connection, adding it to potentially already existing thresholds. + ## conn_duration_threshold_crossed will be raised for each set threshold. + ## + ## cid: The connection id. + ## + ## threshold: Threshold in seconds. + ## + ## Returns: T on success, F on failure. + global set_duration_threshold: function(c: connection, threshold: interval): bool; + ## Deletes a byte threshold for connection sizes. ## ## cid: The connection id. @@ -58,6 +69,15 @@ export { ## Returns: T on success, F on failure. global delete_packets_threshold: function(c: connection, threshold: count, is_orig: bool): bool; + ## Deletes a duration threshold for a connection. + ## + ## cid: The connection id. + ## + ## threshold: Threshold in packets. + ## + ## Returns: T on success, F on failure. + global delete_duration_threshold: function(c: connection, threshold: interval): bool; + ## Generated for a connection that crossed a set byte threshold ## ## c: the connection @@ -75,12 +95,26 @@ export { ## ## is_orig: True if the threshold was crossed by the originator of the connection global packets_threshold_crossed: event(c: connection, threshold: count, is_orig: bool); + + ## Generated for a connection that crossed a set duration threshold. Note that this event is + ## not raised at the exact moment that a duration threshold is crossed; instead it is raised + ## when the next packet is seen after the threshold has been crossed. On a connection that is + ## idle, this can be raised significantly later. + ## + ## c: the connection + ## + ## threshold: the threshold that was set + ## + ## is_orig: True if the threshold was crossed by the originator of the connection + global duration_threshold_crossed: event(c: connection, threshold: interval, is_orig: bool); } redef record connection += { thresholds: ConnThreshold::Thresholds &optional; }; +type threshold_type: enum { BYTES, PACKETS, DURATION }; + function set_conn(c: connection) { if ( c?$thresholds ) @@ -114,43 +148,77 @@ function find_min_threshold(t: set[count]): count return min; } -function set_current_threshold(c: connection, bytes: bool, is_orig: bool): bool +function find_min_duration_threshold(t: set[interval]): interval + { + if ( |t| == 0 ) + return 0secs; + + local first = T; + local min: interval = 0 secs; + + for ( i in t ) + { + if ( first ) + { + min = i; + first = F; + } + else + { + if ( i < min ) + min = i; + } + } + + return min; + } + +function set_current_threshold(c: connection, ttype: threshold_type, is_orig: bool): bool { local t: count = 0; local cur: count = 0; + local td: interval = 0 secs; + local curd: interval = 0 secs; - if ( bytes && is_orig ) + if ( ttype == BYTES && is_orig ) { t = find_min_threshold(c$thresholds$orig_byte); cur = get_current_conn_bytes_threshold(c$id, is_orig); } - else if ( bytes && ! is_orig ) + else if ( ttype == BYTES && ! is_orig ) { t = find_min_threshold(c$thresholds$resp_byte); cur = get_current_conn_bytes_threshold(c$id, is_orig); } - else if ( ! bytes && is_orig ) + else if ( ttype == PACKETS && is_orig ) { t = find_min_threshold(c$thresholds$orig_packet); cur = get_current_conn_packets_threshold(c$id, is_orig); } - else if ( ! bytes && ! is_orig ) + else if ( ttype == PACKETS && ! is_orig ) { t = find_min_threshold(c$thresholds$resp_packet); cur = get_current_conn_packets_threshold(c$id, is_orig); } + else if ( ttype == DURATION ) + { + td = find_min_duration_threshold(c$thresholds$duration); + curd = get_current_conn_duration_threshold(c$id); + } - if ( t == cur ) + if ( t == cur && td == curd ) return T; - if ( bytes && is_orig ) + if ( ttype == BYTES && is_orig ) return set_current_conn_bytes_threshold(c$id, t, T); - else if ( bytes && ! is_orig ) + else if ( ttype == BYTES && ! is_orig ) return set_current_conn_bytes_threshold(c$id, t, F); - else if ( ! bytes && is_orig ) + else if ( ttype == PACKETS && is_orig ) return set_current_conn_packets_threshold(c$id, t, T); - else if ( ! bytes && ! is_orig ) + else if ( ttype == PACKETS && ! is_orig ) return set_current_conn_packets_threshold(c$id, t, F); + else if ( ttype == DURATION ) + return set_current_conn_duration_threshold(c$id, td); } function set_bytes_threshold(c: connection, threshold: count, is_orig: bool): bool @@ -165,7 +233,7 @@ function set_bytes_threshold(c: connection, threshold: count, is_orig: bool): bo else add c$thresholds$resp_byte[threshold]; - return set_current_threshold(c, T, is_orig); + return set_current_threshold(c, BYTES, is_orig); } function set_packets_threshold(c: connection, threshold: count, is_orig: bool): bool @@ -180,7 +248,19 @@ function set_packets_threshold(c: connection, threshold: count, is_orig: bool): else add c$thresholds$resp_packet[threshold]; - return set_current_threshold(c, F, is_orig); + return set_current_threshold(c, PACKETS, is_orig); + } + +function set_duration_threshold(c: connection, threshold: interval): bool + { + set_conn(c); + + if ( threshold == 0 secs ) + return F; + + add c$thresholds$duration[threshold]; + + return set_current_threshold(c, DURATION, T); } function delete_bytes_threshold(c: connection, threshold: count, is_orig: bool): bool @@ -190,13 +270,13 @@ function delete_bytes_threshold(c: connection, threshold: count, is_orig: bool): if ( is_orig && threshold in c$thresholds$orig_byte ) { delete c$thresholds$orig_byte[threshold]; - set_current_threshold(c, T, is_orig); + set_current_threshold(c, BYTES, is_orig); return T; } else if ( ! is_orig && threshold in c$thresholds$resp_byte ) { delete c$thresholds$resp_byte[threshold]; - set_current_threshold(c, T, is_orig); + set_current_threshold(c, BYTES, is_orig); return T; } @@ -210,13 +290,27 @@ function delete_packets_threshold(c: connection, threshold: count, is_orig: bool if ( is_orig && threshold in c$thresholds$orig_packet ) { delete c$thresholds$orig_packet[threshold]; - set_current_threshold(c, F, is_orig); + set_current_threshold(c, PACKETS, is_orig); return T; } else if ( ! is_orig && threshold in c$thresholds$resp_packet ) { delete c$thresholds$resp_packet[threshold]; - set_current_threshold(c, F, is_orig); + set_current_threshold(c, PACKETS, is_orig); + return T; + } + + return F; + } + +function delete_duration_threshold(c: connection, threshold: interval): bool + { + set_conn(c); + + if ( threshold in c$thresholds$duration ) + { + delete c$thresholds$duration[threshold]; + set_current_threshold(c, DURATION, T); return T; } @@ -225,6 +319,9 @@ function delete_packets_threshold(c: connection, threshold: count, is_orig: bool event conn_bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) &priority=5 { + if ( ! c?$thresholds ) + return; + if ( is_orig && threshold in c$thresholds$orig_byte ) { delete c$thresholds$orig_byte[threshold]; @@ -236,11 +333,14 @@ event conn_bytes_threshold_crossed(c: connection, threshold: count, is_orig: boo event ConnThreshold::bytes_threshold_crossed(c, threshold, is_orig); } - set_current_threshold(c, T, is_orig); + set_current_threshold(c, BYTES, is_orig); } event conn_packets_threshold_crossed(c: connection, threshold: count, is_orig: bool) &priority=5 { + if ( ! c?$thresholds ) + return; + if ( is_orig && threshold in c$thresholds$orig_packet ) { delete c$thresholds$orig_packet[threshold]; @@ -252,5 +352,19 @@ event conn_packets_threshold_crossed(c: connection, threshold: count, is_orig: b event ConnThreshold::packets_threshold_crossed(c, threshold, is_orig); } - set_current_threshold(c, F, is_orig); + set_current_threshold(c, PACKETS, is_orig); + } + +event conn_duration_threshold_crossed(c: connection, threshold: interval, is_orig: bool) &priority=5 + { + if ( ! c?$thresholds ) + return; + + if ( threshold in c$thresholds$duration ) + { + delete c$thresholds$duration[threshold]; + event ConnThreshold::duration_threshold_crossed(c, threshold, is_orig); + } + + set_current_threshold(c, DURATION, is_orig); } diff --git a/src/analyzer/protocol/conn-size/ConnSize.cc b/src/analyzer/protocol/conn-size/ConnSize.cc index 1b18335e7f..6a8d911e4c 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.cc +++ b/src/analyzer/protocol/conn-size/ConnSize.cc @@ -13,8 +13,9 @@ using namespace analyzer::conn_size; ConnSize_Analyzer::ConnSize_Analyzer(Connection* c) : Analyzer("CONNSIZE", c), orig_bytes(), resp_bytes(), orig_pkts(), resp_pkts(), - orig_bytes_thresh(), resp_bytes_thresh(), orig_pkts_thresh(), resp_pkts_thresh() + orig_bytes_thresh(), resp_bytes_thresh(), orig_pkts_thresh(), resp_pkts_thresh(), duration_thresh() { + start_time = c->StartTime(); } @@ -54,7 +55,7 @@ void ConnSize_Analyzer::ThresholdEvent(EventHandlerPtr f, uint64 threshold, bool }); } -void ConnSize_Analyzer::CheckSizes(bool is_orig) +void ConnSize_Analyzer::CheckThresholds(bool is_orig) { if ( is_orig ) { @@ -84,6 +85,19 @@ void ConnSize_Analyzer::CheckSizes(bool is_orig) resp_pkts_thresh = 0; } } + + if ( duration_thresh != 0 ) + { + if ( duration_thresh > ( network_time - start_time ) && conn_duration_threshold_crossed ) + { + ConnectionEventFast(conn_duration_threshold_crossed, { + BuildConnVal(), + new Val(duration_thresh, TYPE_INTERVAL), + val_mgr->GetBool(is_orig), + }); + duration_thresh = 0; + } + } } void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) @@ -101,10 +115,10 @@ void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, resp_pkts ++; } - CheckSizes(is_orig); + CheckThresholds(is_orig); } -void ConnSize_Analyzer::SetThreshold(uint64 threshold, bool bytes, bool orig) +void ConnSize_Analyzer::SetByteAndPacketThreshold(uint64 threshold, bool bytes, bool orig) { if ( bytes ) { @@ -122,10 +136,10 @@ void ConnSize_Analyzer::SetThreshold(uint64 threshold, bool bytes, bool orig) } // Check if threshold is already crossed. - CheckSizes(orig); + CheckThresholds(orig); } -uint64_t ConnSize_Analyzer::GetThreshold(bool bytes, bool orig) +uint64_t ConnSize_Analyzer::GetByteAndPacketThreshold(bool bytes, bool orig) { if ( bytes ) { @@ -143,6 +157,14 @@ uint64_t ConnSize_Analyzer::GetThreshold(bool bytes, bool orig) } } +void ConnSize_Analyzer::SetDurationThreshold(double duration) + { + duration_thresh = duration; + + // for duration thresholds, it does not matter which direction we check. + CheckThresholds(true); + } + void ConnSize_Analyzer::UpdateConnVal(RecordVal *conn_val) { // RecordType *connection_type is decleared in NetVar.h @@ -181,4 +203,3 @@ void ConnSize_Analyzer::FlipRoles() orig_pkts = resp_pkts; resp_pkts = tmp; } - diff --git a/src/analyzer/protocol/conn-size/ConnSize.h b/src/analyzer/protocol/conn-size/ConnSize.h index b272f8539c..106b457452 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.h +++ b/src/analyzer/protocol/conn-size/ConnSize.h @@ -21,8 +21,11 @@ public: void UpdateConnVal(RecordVal *conn_val) override; void FlipRoles() override; - void SetThreshold(uint64_t threshold, bool bytes, bool orig); - uint64 GetThreshold(bool bytes, bool orig); + void SetByteAndPacketThreshold(uint64_t threshold, bool bytes, bool orig); + uint64 GetByteAndPacketThreshold(bool bytes, bool orig); + + void SetDurationThreshold(double duration); + double GetDurationThreshold() { return duration_thresh; }; static analyzer::Analyzer* Instantiate(Connection* conn) { return new ConnSize_Analyzer(conn); } @@ -30,7 +33,7 @@ public: protected: void DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) override; - void CheckSizes(bool is_orig); + void CheckThresholds(bool is_orig); void ThresholdEvent(EventHandlerPtr f, uint64 threshold, bool is_orig); @@ -43,6 +46,9 @@ protected: uint64_t resp_bytes_thresh; uint64_t orig_pkts_thresh; uint64_t resp_pkts_thresh; + + double start_time; + double duration_thresh; }; } } // namespace analyzer::* diff --git a/src/analyzer/protocol/conn-size/events.bif b/src/analyzer/protocol/conn-size/events.bif index 9b1007ec3b..7d22133d65 100644 --- a/src/analyzer/protocol/conn-size/events.bif +++ b/src/analyzer/protocol/conn-size/events.bif @@ -1,6 +1,6 @@ ## Generated for a connection that crossed a set byte threshold. Note that this ## is a low level event that should usually be avoided for user code. Use -## ConnThreshold::bytes_threshold_crossed instead. +## :zeek:see:`ConnThreshold::bytes_threshold_crossed` instead. ## ## c: the connection ## @@ -9,12 +9,13 @@ ## is_orig: true if the threshold was crossed by the originator of the connection ## ## .. zeek:see:: set_current_conn_packets_threshold set_current_conn_bytes_threshold conn_packets_threshold_crossed -## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## get_current_conn_bytes_threshold get_current_conn_packets_threshold conn_duration_threshold_crossed +## set_current_conn_duration_threshold get_current_conn_duration_threshold event conn_bytes_threshold_crossed%(c: connection, threshold: count, is_orig: bool%); ## Generated for a connection that crossed a set packet threshold. Note that this ## is a low level event that should usually be avoided for user code. Use -## ConnThreshold::bytes_threshold_crossed instead. +## :zeek:see:`ConnThreshold::packets_threshold_crossed` instead. ## ## c: the connection ## @@ -23,5 +24,25 @@ event conn_bytes_threshold_crossed%(c: connection, threshold: count, is_orig: bo ## is_orig: true if the threshold was crossed by the originator of the connection ## ## .. zeek:see:: set_current_conn_packets_threshold set_current_conn_bytes_threshold conn_bytes_threshold_crossed -## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## get_current_conn_bytes_threshold get_current_conn_packets_threshold conn_duration_threshold_crossed +## set_current_conn_duration_threshold get_current_conn_duration_threshold event conn_packets_threshold_crossed%(c: connection, threshold: count, is_orig: bool%); + +## Generated for a connection that crossed a set duration threshold. Note that this +## is a low level event that should usually be avoided for user code. Use +## :zeek:see:`ConnThreshold::duration_threshold_crossed` instead. +## +## Note that this event is not raised at the exact moment that a duration threshold is crossed; instead +## it is raised when the next packet is seen after the threshold has been crossed. On a connection that is +## idle, this can be raised significantly later. +## +## c: the connection +## +## threshold: the threshold that was set +## +## is_orig: true if the threshold was crossed by the originator of the connection +## +## .. zeek:see:: set_current_conn_packets_threshold set_current_conn_bytes_threshold conn_bytes_threshold_crossed +## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## set_current_conn_duration_threshold get_current_conn_duration_threshold +event conn_duration_threshold_crossed%(c: connection, threshold: interval, is_orig: bool%); diff --git a/src/analyzer/protocol/conn-size/functions.bif b/src/analyzer/protocol/conn-size/functions.bif index 9dc91bb722..74d153363e 100644 --- a/src/analyzer/protocol/conn-size/functions.bif +++ b/src/analyzer/protocol/conn-size/functions.bif @@ -18,7 +18,7 @@ static analyzer::Analyzer* GetConnsizeAnalyzer(Val* cid) ## Sets the current byte threshold for connection sizes, overwriting any potential old ## threshold. Be aware that in nearly any case you will want to use the high level API -## instead (ConnThreshold::set_bytes_threshold). +## instead (:zeek:see:`ConnThreshold::set_bytes_threshold`). ## ## cid: The connection id. ## @@ -27,21 +27,22 @@ static analyzer::Analyzer* GetConnsizeAnalyzer(Val* cid) ## is_orig: If true, threshold is set for bytes from originator, otherwhise for bytes from responder. ## ## .. zeek:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## set_current_conn_duration_threshold get_current_conn_duration_threshold function set_current_conn_bytes_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) return val_mgr->GetBool(0); - static_cast(a)->SetThreshold(threshold, 1, is_orig); + static_cast(a)->SetByteAndPacketThreshold(threshold, 1, is_orig); return val_mgr->GetBool(1); %} ## Sets a threshold for connection packets, overwtiting any potential old thresholds. ## Be aware that in nearly any case you will want to use the high level API -## instead (ConnThreshold::set_packets_threshold). +## instead (:zeek:see:`ConnThreshold::set_packets_threshold`). ## ## cid: The connection id. ## @@ -50,19 +51,42 @@ function set_current_conn_bytes_threshold%(cid: conn_id, threshold: count, is_or ## is_orig: If true, threshold is set for packets from originator, otherwhise for packets from responder. ## ## .. zeek:see:: set_current_conn_bytes_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## set_current_conn_duration_threshold get_current_conn_duration_threshold function set_current_conn_packets_threshold%(cid: conn_id, threshold: count, is_orig: bool%): bool %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) return val_mgr->GetBool(0); - static_cast(a)->SetThreshold(threshold, 0, is_orig); + static_cast(a)->SetByteAndPacketThreshold(threshold, 0, is_orig); return val_mgr->GetBool(1); %} -## Gets the current byte threshold size for a connection. +## Sets the current duration threshold for connection, overwriting any potential old +## threshold. Be aware that in nearly any case you will want to use the high level API +## instead (:zeek:see:`ConnThreshold::set_duration_threshold`). +## +## cid: The connection id. +## +## threshold: Threshold in seconds. +## +## .. zeek:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_current_conn_bytes_threshold get_current_conn_packets_threshold +## get_current_conn_duration_threshold +function set_current_conn_duration_threshold%(cid: conn_id, threshold: interval%): bool + %{ + analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); + if ( ! a ) + return val_mgr->GetBool(0); + + static_cast(a)->SetDurationThreshold(threshold); + + return val_mgr->GetBool(1); + %} + +# Gets the current byte threshold size for a connection. ## ## cid: The connection id. ## @@ -71,14 +95,15 @@ function set_current_conn_packets_threshold%(cid: conn_id, threshold: count, is_ ## Returns: 0 if no threshold is set or the threshold in bytes ## ## .. zeek:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_current_conn_packets_threshold +## get_current_conn_packets_threshold set_current_conn_duration_threshold +## get_current_conn_duration_threshold function get_current_conn_bytes_threshold%(cid: conn_id, is_orig: bool%): count %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) return val_mgr->GetCount(0); - return val_mgr->GetCount(static_cast(a)->GetThreshold(1, is_orig)); + return val_mgr->GetCount(static_cast(a)->GetByteAndPacketThreshold(1, is_orig)); %} ## Gets the current packet threshold size for a connection. @@ -90,13 +115,29 @@ function get_current_conn_bytes_threshold%(cid: conn_id, is_orig: bool%): count ## Returns: 0 if no threshold is set or the threshold in packets ## ## .. zeek:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed -## get_current_conn_bytes_threshold +## get_current_conn_bytes_threshold set_current_conn_duration_threshold get_current_conn_duration_threshold function get_current_conn_packets_threshold%(cid: conn_id, is_orig: bool%): count %{ analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); if ( ! a ) return val_mgr->GetCount(0); - return val_mgr->GetCount(static_cast(a)->GetThreshold(0, is_orig)); + return val_mgr->GetCount(static_cast(a)->GetByteAndPacketThreshold(0, is_orig)); %} +## Gets the current duration threshold size for a connection. +## +## cid: The connection id. +## +## Returns: 0 if no threshold is set or the threshold in seconds +## +## .. zeek:see:: set_current_conn_packets_threshold conn_bytes_threshold_crossed conn_packets_threshold_crossed +## get_current_conn_packets_threshold set_current_conn_duration_threshold +function get_current_conn_duration_threshold%(cid: conn_id%): interval + %{ + analyzer::Analyzer* a = GetConnsizeAnalyzer(cid); + if ( ! a ) + return new Val(0.0, TYPE_INTERVAL); + + return new Val(static_cast(a)->GetDurationThreshold(), TYPE_INTERVAL); + %} diff --git a/testing/btest/Baseline/core.conn-size-threshold/.stderr b/testing/btest/Baseline/core.conn-size-threshold/.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/core.conn-size-threshold/.stdout b/testing/btest/Baseline/core.conn-size-threshold/.stdout index 76ad7c0696..77e3ebf68f 100644 --- a/testing/btest/Baseline/core.conn-size-threshold/.stdout +++ b/testing/btest/Baseline/core.conn-size-threshold/.stdout @@ -2,11 +2,14 @@ 0 0 0 +0.0 Threshold set for [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp] 3000 2000 63 50 +0.0 +triggered duration, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 0.1, T triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2000, F triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 3000, T triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 50, F @@ -14,10 +17,12 @@ triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, 0 0 0 +0.0 Threshold set for [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp] 3000 2000 63 50 +0.1 triggered bytes, [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp], 2000, F triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 63, T diff --git a/testing/btest/Baseline/scripts.base.protocols.conn.threshold-delete/.stderr b/testing/btest/Baseline/scripts.base.protocols.conn.threshold-delete/.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/scripts.base.protocols.conn.threshold-delete/.stdout b/testing/btest/Baseline/scripts.base.protocols.conn.threshold-delete/.stdout new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout b/testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout index f5ae35abc3..0b59896e78 100644 --- a/testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout +++ b/testing/btest/Baseline/scripts.base.protocols.conn.threshold/.stdout @@ -1,10 +1,12 @@ Threshold set for [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp] triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 1, T +triggered duration, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 0.2, T triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2000, F triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2500, T triggered bytes, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 2700, T triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 50, F Threshold set for [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp] triggered bytes, [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp], 1, T +triggered duration, [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp], 0.2, T triggered bytes, [orig_h=192.168.1.77, orig_p=57655/tcp, resp_h=209.197.168.151, resp_p=1024/tcp], 2000, F triggered packets, [orig_h=192.168.1.77, orig_p=57640/tcp, resp_h=66.198.80.67, resp_p=6667/tcp], 52, F diff --git a/testing/btest/core/conn-size-threshold.zeek b/testing/btest/core/conn-size-threshold.zeek index d886846df5..02410a3001 100644 --- a/testing/btest/core/conn-size-threshold.zeek +++ b/testing/btest/core/conn-size-threshold.zeek @@ -1,5 +1,6 @@ # @TEST-EXEC: zeek -r $TRACES/irc-dcc-send.trace %INPUT # @TEST-EXEC: btest-diff .stdout +# @TEST-EXEC: btest-diff .stderr event connection_established(c: connection) { @@ -7,6 +8,7 @@ event connection_established(c: connection) print get_current_conn_bytes_threshold(c$id, F); print get_current_conn_packets_threshold(c$id, T); print get_current_conn_packets_threshold(c$id, F); + print get_current_conn_duration_threshold(c$id); print fmt("Threshold set for %s", cat(c$id)); set_current_conn_bytes_threshold(c$id, 3000, T); @@ -15,10 +17,13 @@ event connection_established(c: connection) set_current_conn_packets_threshold(c$id, 50, F); set_current_conn_packets_threshold(c$id, 63, T); + set_current_conn_duration_threshold(c$id, 0.1 secs); + print get_current_conn_bytes_threshold(c$id, T); print get_current_conn_bytes_threshold(c$id, F); print get_current_conn_packets_threshold(c$id, T); print get_current_conn_packets_threshold(c$id, F); + print get_current_conn_duration_threshold(c$id); } event conn_bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) @@ -30,3 +35,8 @@ event conn_packets_threshold_crossed(c: connection, threshold: count, is_orig: b { print "triggered packets", c$id, threshold, is_orig; } + +event conn_duration_threshold_crossed(c: connection, threshold: interval, is_orig: bool) + { + print "triggered duration", c$id, threshold, is_orig; + } diff --git a/testing/btest/scripts/base/protocols/conn/threshold-delete.zeek b/testing/btest/scripts/base/protocols/conn/threshold-delete.zeek new file mode 100644 index 0000000000..e15e2013fd --- /dev/null +++ b/testing/btest/scripts/base/protocols/conn/threshold-delete.zeek @@ -0,0 +1,30 @@ +# @TEST-EXEC: zeek -r $TRACES/irc-dcc-send.trace %INPUT +# @TEST-EXEC: btest-diff .stdout +# @TEST-EXEC: btest-diff .stderr +# +# This tests that no events are raised once all thresholds have been deleted. + +event connection_established(c: connection) + { + ConnThreshold::set_bytes_threshold(c, 1, T); + ConnThreshold::delete_bytes_threshold(c, 1, T); + ConnThreshold::set_duration_threshold(c, 0.1secs); + ConnThreshold::delete_duration_threshold(c, 0.1secs); + ConnThreshold::set_packets_threshold(c, 63, T); + ConnThreshold::delete_packets_threshold(c, 63, T); + } + +event ConnThreshold::bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) + { + print "triggered bytes", c$id, threshold, is_orig; + } + +event ConnThreshold::packets_threshold_crossed(c: connection, threshold: count, is_orig: bool) + { + print "triggered packets", c$id, threshold, is_orig; + } + +event ConnThreshold::duration_threshold_crossed(c: connection, threshold: interval, is_orig: bool) + { + print "triggered duration", c$id, threshold, is_orig; + } diff --git a/testing/btest/scripts/base/protocols/conn/threshold.zeek b/testing/btest/scripts/base/protocols/conn/threshold.zeek index 4ab01b4dbf..7bdca12861 100644 --- a/testing/btest/scripts/base/protocols/conn/threshold.zeek +++ b/testing/btest/scripts/base/protocols/conn/threshold.zeek @@ -10,6 +10,8 @@ event connection_established(c: connection) ConnThreshold::set_bytes_threshold(c, 3000, T); ConnThreshold::delete_bytes_threshold(c, 3000, T); ConnThreshold::set_bytes_threshold(c, 2000, F); + ConnThreshold::set_duration_threshold(c, 0.1secs); + ConnThreshold::set_duration_threshold(c, 0.2secs); ConnThreshold::set_packets_threshold(c, 50, F); ConnThreshold::set_packets_threshold(c, 51, F); @@ -17,6 +19,7 @@ event connection_established(c: connection) ConnThreshold::delete_packets_threshold(c, 51, F); ConnThreshold::set_packets_threshold(c, 63, T); ConnThreshold::delete_packets_threshold(c, 63, T); + ConnThreshold::delete_duration_threshold(c, 0.1secs); } event ConnThreshold::bytes_threshold_crossed(c: connection, threshold: count, is_orig: bool) @@ -28,3 +31,8 @@ event ConnThreshold::packets_threshold_crossed(c: connection, threshold: count, { print "triggered packets", c$id, threshold, is_orig; } + +event ConnThreshold::duration_threshold_crossed(c: connection, threshold: interval, is_orig: bool) + { + print "triggered duration", c$id, threshold, is_orig; + }