@ -57,11 +57,116 @@ static uint32_t SRepGetVersion(void)
return srep_version ;
}
void SRepResetVersion ( void )
{
srep_version = 0 ;
}
static uint32_t SRepGetEffectiveVersion ( void )
{
return SC_ATOMIC_GET ( srep_eversion ) ;
}
static void SRepCIDRFreeUserData ( void * data )
{
if ( data ! = NULL )
SCFree ( data ) ;
return ;
}
static void SRepCIDRAddNetblock ( SRepCIDRTree * cidr_ctx , char * ip , int cat , int value )
{
SReputation * user_data = NULL ;
if ( ( user_data = SCMalloc ( sizeof ( SReputation ) ) ) = = NULL ) {
SCLogError ( SC_ERR_FATAL , " Error allocating memory. Exiting " ) ;
exit ( EXIT_FAILURE ) ;
}
memset ( user_data , 0x00 , sizeof ( SReputation ) ) ;
user_data - > version = SRepGetVersion ( ) ;
user_data - > rep [ cat ] = value ;
if ( strchr ( ip , ' : ' ) ! = NULL ) {
if ( cidr_ctx - > srepIPV6_tree [ cat ] = = NULL ) {
cidr_ctx - > srepIPV6_tree [ cat ] = SCRadixCreateRadixTree ( SRepCIDRFreeUserData , NULL ) ;
if ( cidr_ctx - > srepIPV6_tree [ cat ] = = NULL ) {
SCLogDebug ( " Error initializing Reputation IPV6 with CIDR module for cat %d " , cat ) ;
exit ( EXIT_FAILURE ) ;
}
SCLogDebug ( " Reputation IPV6 with CIDR module for cat %d initialized " , cat ) ;
}
SCLogDebug ( " adding ipv6 host %s " , ip ) ;
if ( SCRadixAddKeyIPV6String ( ip , cidr_ctx - > srepIPV6_tree [ cat ] , ( void * ) user_data ) = = NULL ) {
SCLogWarning ( SC_ERR_INVALID_VALUE ,
" failed to add ipv6 host %s " , ip ) ;
}
} else {
if ( cidr_ctx - > srepIPV4_tree [ cat ] = = NULL ) {
cidr_ctx - > srepIPV4_tree [ cat ] = SCRadixCreateRadixTree ( SRepCIDRFreeUserData , NULL ) ;
if ( cidr_ctx - > srepIPV4_tree [ cat ] = = NULL ) {
SCLogDebug ( " Error initializing Reputation IPV4 with CIDR module for cat %d " , cat ) ;
exit ( EXIT_FAILURE ) ;
}
SCLogDebug ( " Reputation IPV4 with CIDR module for cat %d initialized " , cat ) ;
}
SCLogDebug ( " adding ipv4 host %s " , ip ) ;
if ( SCRadixAddKeyIPV4String ( ip , cidr_ctx - > srepIPV4_tree [ cat ] , ( void * ) user_data ) = = NULL ) {
SCLogWarning ( SC_ERR_INVALID_VALUE ,
" failed to add ipv4 host %s " , ip ) ;
}
}
}
static uint8_t SRepCIDRGetIPv4IPRep ( SRepCIDRTree * cidr_ctx , uint8_t * ipv4_addr , uint8_t cat )
{
void * user_data = NULL ;
( void ) SCRadixFindKeyIPV4BestMatch ( ipv4_addr , cidr_ctx - > srepIPV4_tree [ cat ] , & user_data ) ;
if ( user_data = = NULL )
return 0 ;
SReputation * r = ( SReputation * ) user_data ;
return r - > rep [ cat ] ;
}
static uint8_t SRepCIDRGetIPv6IPRep ( SRepCIDRTree * cidr_ctx , uint8_t * ipv6_addr , uint8_t cat )
{
void * user_data = NULL ;
( void ) SCRadixFindKeyIPV6BestMatch ( ipv6_addr , cidr_ctx - > srepIPV6_tree [ cat ] , & user_data ) ;
if ( user_data = = NULL )
return 0 ;
SReputation * r = ( SReputation * ) user_data ;
return r - > rep [ cat ] ;
}
uint8_t SRepCIDRGetIPRepSrc ( SRepCIDRTree * cidr_ctx , Packet * p , uint8_t cat , uint32_t version )
{
uint8_t rep = 0 ;
if ( PKT_IS_IPV4 ( p ) )
rep = SRepCIDRGetIPv4IPRep ( cidr_ctx , ( uint8_t * ) GET_IPV4_SRC_ADDR_PTR ( p ) , cat ) ;
else if ( PKT_IS_IPV6 ( p ) )
rep = SRepCIDRGetIPv6IPRep ( cidr_ctx , ( uint8_t * ) GET_IPV6_SRC_ADDR ( p ) , cat ) ;
return rep ;
}
uint8_t SRepCIDRGetIPRepDst ( SRepCIDRTree * cidr_ctx , Packet * p , uint8_t cat , uint32_t version )
{
uint8_t rep = 0 ;
if ( PKT_IS_IPV4 ( p ) )
rep = SRepCIDRGetIPv4IPRep ( cidr_ctx , ( uint8_t * ) GET_IPV4_DST_ADDR_PTR ( p ) , cat ) ;
else if ( PKT_IS_IPV6 ( p ) )
rep = SRepCIDRGetIPv6IPRep ( cidr_ctx , ( uint8_t * ) GET_IPV6_DST_ADDR ( p ) , cat ) ;
return rep ;
}
/** \brief Increment effective reputation version after
* a rule / reputatio reload is complete . */
void SRepReloadComplete ( void )
@ -162,7 +267,7 @@ static int SRepCatSplitLine(char *line, uint8_t *cat, char *shortname, size_t sh
* \ retval 1 header
* \ retval - 1 boo
*/
static int SRepSplitLine ( char * line , uint32_t * ip , uint8_t * cat , uint8_t * value )
static int SRepSplitLine ( SRepCIDRTree * cidr_ctx , char * line , uint32_t * ip , uint8_t * cat , uint8_t * value )
{
size_t line_len = strlen ( line ) ;
char * ptrs [ 3 ] = { NULL , NULL , NULL } ;
@ -200,11 +305,6 @@ static int SRepSplitLine(char *line, uint32_t *ip, uint8_t *cat, uint8_t *value)
if ( strcmp ( ptrs [ 0 ] , " ip " ) = = 0 )
return 1 ;
uint32_t addr ;
if ( inet_pton ( AF_INET , ptrs [ 0 ] , & addr ) < = 0 ) {
return - 1 ;
}
int c = atoi ( ptrs [ 1 ] ) ;
if ( c < 0 | | c > = SREP_MAX_CATS ) {
return - 1 ;
@ -215,9 +315,20 @@ static int SRepSplitLine(char *line, uint32_t *ip, uint8_t *cat, uint8_t *value)
return - 1 ;
}
* ip = addr ;
* cat = c ;
* value = v ;
if ( strchr ( ptrs [ 0 ] , ' / ' ) ! = NULL ) {
SRepCIDRAddNetblock ( cidr_ctx , ptrs [ 0 ] , c , v ) ;
return 1 ;
} else {
uint32_t addr ;
if ( inet_pton ( AF_INET , ptrs [ 0 ] , & addr ) < = 0 ) {
return - 1 ;
}
* ip = addr ;
* cat = c ;
* value = v ;
}
return 0 ;
}
@ -246,7 +357,24 @@ uint8_t SRepCatGetByShortname(char *shortname)
return 0 ;
}
int SRepLoadCatFile ( char * filename )
static int SRepLoadCatFile ( char * filename )
{
int r = 0 ;
FILE * fp = fopen ( filename , " r " ) ;
if ( fp = = NULL ) {
SCLogError ( SC_ERR_OPENING_RULE_FILE , " opening ip rep file %s: %s " , filename , strerror ( errno ) ) ;
return - 1 ;
}
r = SRepLoadCatFileFromFD ( fp ) ;
fclose ( fp ) ;
fp = NULL ;
return r ;
}
int SRepLoadCatFileFromFD ( FILE * fp )
{
char line [ 8192 ] = " " ;
Address a ;
@ -256,12 +384,6 @@ int SRepLoadCatFile(char *filename)
BUG_ON ( SRepGetVersion ( ) > 0 ) ;
FILE * fp = fopen ( filename , " r " ) ;
if ( fp = = NULL ) {
SCLogError ( SC_ERR_OPENING_RULE_FILE , " opening ip rep file %s: %s " , filename , strerror ( errno ) ) ;
return - 1 ;
}
while ( fgets ( line , ( int ) sizeof ( line ) , fp ) ! = NULL ) {
size_t len = strlen ( line ) ;
if ( len = = 0 )
@ -290,8 +412,6 @@ int SRepLoadCatFile(char *filename)
SCLogError ( SC_ERR_NO_REPUTATION , " bad line \" %s \" " , line ) ;
}
}
fclose ( fp ) ;
fp = NULL ;
SCLogDebug ( " IP Rep categories: " ) ;
int i ;
@ -303,19 +423,31 @@ int SRepLoadCatFile(char *filename)
return 0 ;
}
static int SRepLoadFile ( char * filename )
static int SRepLoadFile ( SRepCIDRTree * cidr_ctx , char * filename )
{
char line [ 8192 ] = " " ;
Address a ;
memset ( & a , 0x00 , sizeof ( a ) ) ;
a . family = AF_INET ;
int r = 0 ;
FILE * fp = fopen ( filename , " r " ) ;
if ( fp = = NULL ) {
SCLogError ( SC_ERR_OPENING_RULE_FILE , " opening ip rep file \" %s\" : %s" , filename , strerror ( errno ) ) ;
SCLogError ( SC_ERR_OPENING_RULE_FILE , " opening ip rep file %s: %s " , filename , strerror ( errno ) ) ;
return - 1 ;
}
r = SRepLoadFileFromFD ( cidr_ctx , fp ) ;
fclose ( fp ) ;
fp = NULL ;
return r ;
}
int SRepLoadFileFromFD ( SRepCIDRTree * cidr_ctx , FILE * fp )
{
char line [ 8192 ] = " " ;
Address a ;
memset ( & a , 0x00 , sizeof ( a ) ) ;
a . family = AF_INET ;
while ( fgets ( line , ( int ) sizeof ( line ) , fp ) ! = NULL ) {
size_t len = strlen ( line ) ;
if ( len = = 0 )
@ -338,7 +470,7 @@ static int SRepLoadFile(char *filename)
uint32_t ip = 0 ;
uint8_t cat = 0 , value = 0 ;
int r = SRepSplitLine ( line, & ip , & cat , & value ) ;
int r = SRepSplitLine ( cidr_ctx, line, & ip , & cat , & value ) ;
if ( r < 0 ) {
SCLogError ( SC_ERR_NO_REPUTATION , " bad line \" %s \" " , line ) ;
} else if ( r = = 0 ) {
@ -394,8 +526,6 @@ static int SRepLoadFile(char *filename)
}
}
}
fclose ( fp ) ;
fp = NULL ;
return 0 ;
}
@ -459,6 +589,18 @@ int SRepInit(DetectEngineCtx *de_ctx)
char * sfile = NULL ;
char * filename = NULL ;
int init = 0 ;
int i = 0 ;
de_ctx - > srepCIDR_ctx = ( SRepCIDRTree * ) SCMalloc ( sizeof ( SRepCIDRTree ) ) ;
if ( de_ctx - > srepCIDR_ctx = = NULL )
exit ( EXIT_FAILURE ) ;
memset ( de_ctx - > srepCIDR_ctx , 0 , sizeof ( SRepCIDRTree ) ) ;
SRepCIDRTree * cidr_ctx = de_ctx - > srepCIDR_ctx ;
for ( i = 0 ; i < SREP_MAX_CATS ; i + + ) {
cidr_ctx - > srepIPV4_tree [ i ] = NULL ;
cidr_ctx - > srepIPV6_tree [ i ] = NULL ;
}
if ( SRepGetVersion ( ) = = 0 ) {
SC_ATOMIC_INIT ( srep_eversion ) ;
@ -502,7 +644,7 @@ int SRepInit(DetectEngineCtx *de_ctx)
sfile = SRepCompleteFilePath ( file - > val ) ;
SCLogInfo ( " Loading reputation file: %s " , sfile ) ;
r = SRepLoadFile ( sfile) ;
r = SRepLoadFile ( cidr_ctx, sfile) ;
if ( r < 0 ) {
if ( de_ctx - > failure_fatal = = 1 ) {
exit ( EXIT_FAILURE ) ;