@ -174,7 +174,7 @@ static DetectThresholdEntry* ThresholdTimeoutCheck(DetectThresholdEntry *head, s
/* check if the 'check' timestamp is not before the creation ts.
* This can happen due to the async nature of the host timeout
* code that also calls this code from a management thread . */
if ( ( ( uint32_t ) tv - > tv_sec < tmp - > tv_sec1 ) | | ( tv - > tv_sec - tmp - > tv_sec 1) < = tmp - > seconds ) {
if ( TIMEVAL_EARLIER ( * tv , tmp - > tv1 ) | | TIMEVAL_DIFF_SEC ( * tv , tmp - > tv 1) < = tmp - > seconds ) {
prev = tmp ;
tmp = tmp - > next ;
continue ;
@ -333,14 +333,14 @@ static inline void RateFilterSetAction(Packet *p, PacketAlert *pa, uint8_t new_a
* \ retval int 1 if threshold reached for this entry
*
*/
static int IsThresholdReached ( DetectThresholdEntry * lookup_tsh , const DetectThresholdData * td , uint32_t packet_time )
static int IsThresholdReached ( DetectThresholdEntry * lookup_tsh , const DetectThresholdData * td , struct timeval packet_time )
{
int ret = 0 ;
/* Check if we have a timeout enabled, if so,
* we still matching ( and enabling the new_action ) */
if ( lookup_tsh - > tv_timeout ! = 0 ) {
if ( ( packet_time - lookup_tsh - > tv_timeout ) > td - > timeout ) {
if ( ( packet_time . tv_sec - lookup_tsh - > tv_timeout ) > td - > timeout ) {
/* Ok, we are done, timeout reached */
lookup_tsh - > tv_timeout = 0 ;
}
@ -352,17 +352,17 @@ static int IsThresholdReached(DetectThresholdEntry* lookup_tsh, const DetectThre
}
else {
/* Update the matching state with the timeout interval */
if ( ( packet_time - lookup_tsh - > tv _sec 1) < td - > seconds ) {
if ( TIMEVAL_DIFF_SEC ( packet_time , lookup_tsh - > tv 1) < td - > seconds ) {
lookup_tsh - > current_count + + ;
if ( lookup_tsh - > current_count > td - > count ) {
/* Then we must enable the new action by setting a
* timeout */
lookup_tsh - > tv_timeout = packet_time ;
lookup_tsh - > tv_timeout = packet_time .tv_sec ;
ret = 1 ;
}
}
else {
lookup_tsh - > tv _sec 1 = packet_time ;
lookup_tsh - > tv 1 = packet_time ;
lookup_tsh - > current_count = 1 ;
}
} /* else - if (lookup_tsh->tv_timeout != 0) */
@ -370,79 +370,49 @@ static int IsThresholdReached(DetectThresholdEntry* lookup_tsh, const DetectThre
return ret ;
}
static void AddEntryToHostStorage ( Host * h , DetectThresholdEntry * e , uint32_t packet_time )
static void AddEntryToHostStorage ( Host * h , DetectThresholdEntry * e , struct timeval packet_time )
{
if ( h & & e ) {
e - > current_count = 1 ;
e - > tv _sec 1 = packet_time ;
e - > tv 1 = packet_time ;
e - > tv_timeout = 0 ;
e - > next = HostGetStorageById ( h , host_threshold_id ) ;
HostSetStorageById ( h , host_threshold_id , e ) ;
}
}
static void AddEntryToIPPairStorage ( IPPair * pair , DetectThresholdEntry * e , uint32_t packet_time )
static void AddEntryToIPPairStorage ( IPPair * pair , DetectThresholdEntry * e , struct timeval packet_time )
{
if ( pair & & e ) {
e - > current_count = 1 ;
e - > tv _sec 1 = packet_time ;
e - > tv 1 = packet_time ;
e - > tv_timeout = 0 ;
e - > next = IPPairGetStorageById ( pair , ippair_threshold_id ) ;
IPPairSetStorageById ( pair , ippair_threshold_id , e ) ;
}
}
static int ThresholdHandlePacketIPPair ( IPPair * pair , Packet * p , const DetectThresholdData * td ,
uint32_t sid , uint32_t gid , PacketAlert * pa )
{
int ret = 0 ;
DetectThresholdEntry * lookup_tsh = ThresholdIPPairLookupEntry ( pair , sid , gid ) ;
SCLogDebug ( " ippair lookup_tsh %p sid %u gid %u " , lookup_tsh , sid , gid ) ;
switch ( td - > type ) {
case TYPE_RATE :
{
SCLogDebug ( " rate_filter " ) ;
ret = 1 ;
if ( lookup_tsh & & IsThresholdReached ( lookup_tsh , td , p - > ts . tv_sec ) ) {
RateFilterSetAction ( p , pa , td - > new_action ) ;
} else if ( ! lookup_tsh ) {
DetectThresholdEntry * e = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
AddEntryToIPPairStorage ( pair , e , p - > ts . tv_sec ) ;
}
break ;
}
default :
{
SCLogError ( SC_ERR_INVALID_VALUE , " type %d is not supported " , td - > type ) ;
break ;
}
}
return ret ;
}
/**
* \ retval 2 silent match ( no alert but apply actions )
* \ retval 1 normal match
* \ retval 0 no match
*
* If a new DetectThresholdEntry is generated to track the threshold
* for this rule , then it will be returned in new_tsh .
*/
static int ThresholdHandlePacketHost ( Host * h , Packet * p , const DetectThresholdData * td ,
static int ThresholdHandlePacket ( Packet * p , DetectThresholdEntry * lookup_tsh ,
DetectThresholdEntry * * new_tsh , const DetectThresholdData * td ,
uint32_t sid , uint32_t gid , PacketAlert * pa )
{
int ret = 0 ;
DetectThresholdEntry * lookup_tsh = ThresholdHostLookupEntry ( h , sid , gid ) ;
SCLogDebug ( " lookup_tsh %p sid %u gid %u " , lookup_tsh , sid , gid ) ;
switch ( td - > type ) {
case TYPE_LIMIT :
{
SCLogDebug ( " limit " ) ;
if ( lookup_tsh ! = NULL ) {
if ( ( p - > ts .tv_sec - lookup_tsh - > tv _sec 1) < td - > seconds ) {
if ( TIMEVAL_DIFF_SEC ( p - > ts , lookup_tsh - > tv1 ) < td - > seconds ) {
lookup_tsh - > current_count + + ;
if ( lookup_tsh - > current_count < = td - > count ) {
@ -451,24 +421,15 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
ret = 2 ;
}
} else {
lookup_tsh - > tv _sec 1 = p - > ts . tv_sec ;
lookup_tsh - > tv 1 = p - > ts ;
lookup_tsh - > current_count = 1 ;
ret = 1 ;
}
} else {
DetectThresholdEntry * e = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
if ( e = = NULL ) {
break ;
}
e - > tv_sec1 = p - > ts . tv_sec ;
e - > current_count = 1 ;
* new_tsh = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
ret = 1 ;
e - > next = HostGetStorageById ( h , host_threshold_id ) ;
HostSetStorageById ( h , host_threshold_id , e ) ;
}
break ;
}
@ -477,7 +438,7 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
SCLogDebug ( " threshold " ) ;
if ( lookup_tsh ! = NULL ) {
if ( ( p - > ts .tv_sec - lookup_tsh - > tv _sec 1) < td - > seconds ) {
if ( TIMEVAL_DIFF_SEC ( p - > ts , lookup_tsh - > tv 1) < td - > seconds ) {
lookup_tsh - > current_count + + ;
if ( lookup_tsh - > current_count > = td - > count ) {
@ -485,23 +446,14 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
lookup_tsh - > current_count = 0 ;
}
} else {
lookup_tsh - > tv _sec 1 = p - > ts . tv_sec ;
lookup_tsh - > tv 1 = p - > ts ;
lookup_tsh - > current_count = 1 ;
}
} else {
if ( td - > count = = 1 ) {
ret = 1 ;
} else {
DetectThresholdEntry * e = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
if ( e = = NULL ) {
break ;
}
e - > current_count = 1 ;
e - > tv_sec1 = p - > ts . tv_sec ;
e - > next = HostGetStorageById ( h , host_threshold_id ) ;
HostSetStorageById ( h , host_threshold_id , e ) ;
* new_tsh = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
}
}
break ;
@ -511,7 +463,7 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
SCLogDebug ( " both " ) ;
if ( lookup_tsh ! = NULL ) {
if ( ( p - > ts .tv_sec - lookup_tsh - > tv _sec 1) < td - > seconds ) {
if ( TIMEVAL_DIFF_SEC ( p - > ts , lookup_tsh - > tv 1) < td - > seconds ) {
/* within time limit */
lookup_tsh - > current_count + + ;
@ -523,7 +475,7 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
}
} else {
/* expired, so reset */
lookup_tsh - > tv _sec 1 = p - > ts . tv_sec ;
lookup_tsh - > tv 1 = p - > ts ;
lookup_tsh - > current_count = 1 ;
/* if we have a limit of 1, this is a match */
@ -532,16 +484,7 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
}
}
} else {
DetectThresholdEntry * e = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
if ( e = = NULL ) {
break ;
}
e - > current_count = 1 ;
e - > tv_sec1 = p - > ts . tv_sec ;
e - > next = HostGetStorageById ( h , host_threshold_id ) ;
HostSetStorageById ( h , host_threshold_id , e ) ;
* new_tsh = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
/* for the first match we return 1 to
* indicate we should alert */
@ -557,35 +500,19 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
SCLogDebug ( " detection_filter " ) ;
if ( lookup_tsh ! = NULL ) {
long double time_diff = ( ( p - > ts . tv_sec + p - > ts . tv_usec / 1000000.0 ) -
( lookup_tsh - > tv_sec1 + lookup_tsh - > tv_usec1 / 1000000.0 ) ) ;
if ( time_diff < td - > seconds ) {
if ( TIMEVAL_DIFF_SEC ( p - > ts , lookup_tsh - > tv1 ) < td - > seconds ) {
/* within timeout */
lookup_tsh - > current_count + + ;
if ( lookup_tsh - > current_count > td - > count ) {
ret = 1 ;
}
} else {
/* expired, reset */
lookup_tsh - > tv_sec1 = p - > ts . tv_sec ;
lookup_tsh - > tv_usec1 = p - > ts . tv_usec ;
lookup_tsh - > tv1 = p - > ts ;
lookup_tsh - > current_count = 1 ;
}
} else {
DetectThresholdEntry * e = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
if ( e = = NULL ) {
break ;
}
e - > current_count = 1 ;
e - > tv_sec1 = p - > ts . tv_sec ;
e - > tv_usec1 = p - > ts . tv_usec ;
e - > next = HostGetStorageById ( h , host_threshold_id ) ;
HostSetStorageById ( h , host_threshold_id , e ) ;
* new_tsh = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
}
break ;
}
@ -594,11 +521,10 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
{
SCLogDebug ( " rate_filter " ) ;
ret = 1 ;
if ( lookup_tsh & & IsThresholdReached ( lookup_tsh , td , p - > ts .tv_sec )) {
if ( lookup_tsh & & IsThresholdReached ( lookup_tsh , td , p - > ts )) {
RateFilterSetAction ( p , pa , td - > new_action ) ;
} else if ( ! lookup_tsh ) {
DetectThresholdEntry * e = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
AddEntryToHostStorage ( h , e , p - > ts . tv_sec ) ;
* new_tsh = DetectThresholdEntryAlloc ( td , p , sid , gid ) ;
}
break ;
}
@ -606,7 +532,43 @@ static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdDa
default :
SCLogError ( SC_ERR_INVALID_VALUE , " type %d is not supported " , td - > type ) ;
}
return ret ;
}
static int ThresholdHandlePacketIPPair ( IPPair * pair , Packet * p , const DetectThresholdData * td ,
uint32_t sid , uint32_t gid , PacketAlert * pa )
{
int ret = 0 ;
DetectThresholdEntry * lookup_tsh = ThresholdIPPairLookupEntry ( pair , sid , gid ) ;
SCLogDebug ( " ippair lookup_tsh %p sid %u gid %u " , lookup_tsh , sid , gid ) ;
DetectThresholdEntry * new_tsh = NULL ;
ret = ThresholdHandlePacket ( p , lookup_tsh , & new_tsh , td , sid , gid , pa ) ;
if ( new_tsh ! = NULL ) {
AddEntryToIPPairStorage ( pair , new_tsh , p - > ts ) ;
}
return ret ;
}
/**
* \ retval 2 silent match ( no alert but apply actions )
* \ retval 1 normal match
* \ retval 0 no match
*/
static int ThresholdHandlePacketHost ( Host * h , Packet * p , const DetectThresholdData * td ,
uint32_t sid , uint32_t gid , PacketAlert * pa )
{
int ret = 0 ;
DetectThresholdEntry * lookup_tsh = ThresholdHostLookupEntry ( h , sid , gid ) ;
SCLogDebug ( " lookup_tsh %p sid %u gid %u " , lookup_tsh , sid , gid ) ;
DetectThresholdEntry * new_tsh = NULL ;
ret = ThresholdHandlePacket ( p , lookup_tsh , & new_tsh , td , sid , gid , pa ) ;
if ( new_tsh ! = NULL ) {
AddEntryToHostStorage ( h , new_tsh , p - > ts ) ;
}
return ret ;
}
@ -618,30 +580,13 @@ static int ThresholdHandlePacketRule(DetectEngineCtx *de_ctx, Packet *p,
DetectThresholdEntry * lookup_tsh = ( DetectThresholdEntry * ) de_ctx - > ths_ctx . th_entry [ s - > num ] ;
SCLogDebug ( " by_rule lookup_tsh %p num %u " , lookup_tsh , s - > num ) ;
switch ( td - > type ) {
case TYPE_RATE :
{
ret = 1 ;
if ( lookup_tsh & & IsThresholdReached ( lookup_tsh , td , p - > ts . tv_sec ) ) {
RateFilterSetAction ( p , pa , td - > new_action ) ;
}
else if ( ! lookup_tsh ) {
DetectThresholdEntry * e = DetectThresholdEntryAlloc ( td , p , s - > id , s - > gid ) ;
if ( e ! = NULL ) {
e - > current_count = 1 ;
e - > tv_sec1 = p - > ts . tv_sec ;
e - > tv_timeout = 0 ;
de_ctx - > ths_ctx . th_entry [ s - > num ] = e ;
}
}
break ;
}
default :
{
SCLogError ( SC_ERR_INVALID_VALUE , " type %d is not supported " , td - > type ) ;
break ;
}
DetectThresholdEntry * new_tsh = NULL ;
ret = ThresholdHandlePacket ( p , lookup_tsh , & new_tsh , td , s - > id , s - > gid , pa ) ;
if ( new_tsh ! = NULL ) {
new_tsh - > tv1 = p - > ts ;
new_tsh - > current_count = 1 ;
new_tsh - > tv_timeout = 0 ;
de_ctx - > ths_ctx . th_entry [ s - > num ] = new_tsh ;
}
return ret ;