@ -315,61 +315,79 @@ static int Unified2Write(Unified2AlertThread *aun)
return 1 ;
}
/**
* \ brief Function to return XFF IP if any . . .
* \ retval 1 if the IP has been found and returned in dstbuf
* \ retval 0 if the IP has not being found or error
*/
static int GetXFFIP ( Packet * p , char * xff_header , char * dstbuf , int dstbuflen )
static int GetXFFIPFromTx ( Packet * p , uint64_t tx_id , char * xff_header , char * dstbuf , int dstbuflen )
{
uint8_t xff_chain [ UNIFIED2_ALERT_XFF_CHAIN_MAXLEN ] ;
HtpState * htp_state = NULL ;
htp_tx_t * tx = NULL ;
uint64_t tx_id = 0 ;
uint64_t total_txs = 0 ;
htp_state = ( HtpState * ) AppLayerGetProtoStateFromPacket ( p ) ;
if ( htp_state = = NULL ) {
SCLogDebug ( " no http state, XFF IP cannot be retrieved " ) ;
goto end ;
return 0 ;
}
total_txs = AppLayerGetTxCnt ( ALPROTO_HTTP , htp_state ) ;
if ( tx_id > = total_txs )
return 0 ;
for ( ; tx_id < total_txs ; tx_id + + ) {
tx = AppLayerGetTx ( ALPROTO_HTTP , htp_state , tx_id ) ;
tx = AppLayerGetTx ( ALPROTO_HTTP , htp_state , tx_id ) ;
if ( tx = = NULL ) {
SCLogDebug ( " tx is NULL, XFF cannot be retrieved " ) ;
return 0 ;
}
if ( tx = = NULL ) {
SCLogDebug ( " tx is NULL, XFF cannot be retrieved " ) ;
continue ;
}
htp_header_t * h_xff = NULL ;
if ( tx - > request_headers ! = NULL ) {
h_xff = htp_table_get_c ( tx - > request_headers , xff_header ) ;
}
if ( h_xff ! = NULL & & bstr_len ( h_xff - > value ) > = UNIFIED2_ALERT_XFF_CHAIN_MINLEN & &
bstr_len ( h_xff - > value ) < UNIFIED2_ALERT_XFF_CHAIN_MAXLEN ) {
htp_header_t * h_xff = NULL ;
if ( tx - > request_headers ! = NULL ) {
h_xff = htp_table_get_c ( tx - > request_headers , xff_header ) ;
memcpy ( xff_chain , bstr_ptr ( h_xff - > value ) , bstr_len ( h_xff - > value ) ) ;
xff_chain [ bstr_len ( h_xff - > value ) ] = 0 ;
/** Check for chained IP's separated by ", ", we will get the last one */
uint8_t * p_xff = memrchr ( xff_chain , ' ' , bstr_len ( h_xff - > value ) ) ;
if ( p_xff = = NULL ) {
p_xff = xff_chain ;
} else {
p_xff + + ;
}
/** Sanity check on extracted IP for IPv4 and IPv6 */
uint32_t ip [ 4 ] ;
if ( inet_pton ( AF_INET , ( char * ) p_xff , ip ) = = 1 | |
inet_pton ( AF_INET6 , ( char * ) p_xff , ip ) = = 1 ) {
strlcpy ( dstbuf , ( char * ) p_xff , dstbuflen ) ;
return 1 ; // OK
}
}
return 0 ;
}
if ( h_xff ! = NULL & & bstr_len ( h_xff - > value ) > = UNIFIED2_ALERT_XFF_CHAIN_MINLEN & &
bstr_len ( h_xff - > value ) < UNIFIED2_ALERT_XFF_CHAIN_MAXLEN ) {
/**
* \ brief Function to return XFF IP if any . . .
* \ retval 1 if the IP has been found and returned in dstbuf
* \ retval 0 if the IP has not being found or error
*/
static int GetXFFIP ( Packet * p , char * xff_header , char * dstbuf , int dstbuflen )
{
HtpState * htp_state = NULL ;
uint64_t tx_id = 0 ;
uint64_t total_txs = 0 ;
memcpy ( xff_chain , bstr_ptr ( h_xff - > value ) , bstr_len ( h_xff - > value ) ) ;
xff_chain [ bstr_len ( h_xff - > value ) ] = 0 ;
/** Check for chained IP's separated by ", ", we will get the last one */
uint8_t * p_xff = memrchr ( xff_chain , ' ' , bstr_len ( h_xff - > value ) ) ;
if ( p_xff = = NULL ) {
p_xff = xff_chain ;
} else {
p_xff + + ;
}
/** Sanity check on extracted IP for IPv4 and IPv6 */
uint32_t ip [ 4 ] ;
if ( inet_pton ( AF_INET , ( char * ) p_xff , ip ) = = 1 | |
inet_pton ( AF_INET6 , ( char * ) p_xff , ip ) = = 1 ) {
strlcpy ( dstbuf , ( char * ) p_xff , dstbuflen ) ;
return 1 ; // OK
}
}
htp_state = ( HtpState * ) AppLayerGetProtoStateFromPacket ( p ) ;
if ( htp_state = = NULL ) {
SCLogDebug ( " no http state, XFF IP cannot be retrieved " ) ;
goto end ;
}
total_txs = AppLayerGetTxCnt ( ALPROTO_HTTP , htp_state ) ;
for ( ; tx_id < total_txs ; tx_id + + ) {
if ( GetXFFIPFromTx ( p , tx_id , xff_header , dstbuf , dstbuflen ) = = 1 )
return 1 ;
}
end :
@ -384,14 +402,16 @@ end:
*/
TmEcode Unified2Alert ( ThreadVars * t , Packet * p , void * data , PacketQueue * pq , PacketQueue * postpq )
{
int ret = 0 ;
Unified2AlertThread * aun = ( Unified2AlertThread * ) data ;
aun - > xff_flags = UNIFIED2_ALERT_XFF_DISABLED ;
if ( p - > alerts . cnt = = 0 & & ! ( p - > flags & PKT_HAS_TAG ) )
return TM_ECODE_OK ;
if ( ! ( aun - > unified2alert_ctx - > xff_mode & UNIFIED2_ALERT_XFF_DISABLED ) & &
p - > flow ! = NULL ) {
/* overwrite mode can only work per u2 block, not per individual
* alert . So we ' ll look for an XFF record once */
if ( ( aun - > unified2alert_ctx - > xff_mode & UNIFIED2_ALERT_XFF_OVERWRITE ) & & p - > flow ! = NULL ) {
FLOWLOCK_RDLOCK ( p - > flow ) ;
if ( AppLayerGetProtoFromPacket ( p ) = = ALPROTO_HTTP ) {
@ -401,34 +421,20 @@ TmEcode Unified2Alert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq, Pa
/** Be sure that we have a nice zeroed buffer */
memset ( aun - > xff_ip , 0 , 4 * sizeof ( uint32_t ) ) ;
if ( aun - > unified2alert_ctx - > xff_mode & UNIFIED2_ALERT_XFF_OVERWRITE ) {
/** We can only have override mode if packet IP version matches
* the XFF IP version , otherwise fall - back to extra data */
if ( inet_pton ( AF_INET , buffer , aun - > xff_ip ) = = 1 ) {
aun - > xff_flags = UNIFIED2_ALERT_XFF_IPV4 ;
if ( PKT_IS_IPV4 ( p ) ) {
aun - > xff_flags | = UNIFIED2_ALERT_XFF_OVERWRITE ;
} else {
aun - > xff_flags | = UNIFIED2_ALERT_XFF_EXTRADATA ;
}
} else if ( inet_pton ( AF_INET6 , buffer , aun - > xff_ip ) = = 1 ) {
aun - > xff_flags = UNIFIED2_ALERT_XFF_IPV6 ;
if ( PKT_IS_IPV6 ( p ) ) {
aun - > xff_flags | = UNIFIED2_ALERT_XFF_OVERWRITE ;
} else {
aun - > xff_flags | = UNIFIED2_ALERT_XFF_EXTRADATA ;
}
/** We can only have override mode if packet IP version matches
* the XFF IP version , otherwise fall - back to extra data */
if ( inet_pton ( AF_INET , buffer , aun - > xff_ip ) = = 1 ) {
SCLogDebug ( " valid ipv4 xff, setting flags %s " , buffer ) ;
if ( PKT_IS_IPV4 ( p ) ) {
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV4 | UNIFIED2_ALERT_XFF_OVERWRITE ) ;
} else {
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV4 | UNIFIED2_ALERT_XFF_EXTRADATA ) ;
}
}
else if ( aun - > unified2alert_ctx - > xff_mode & UNIFIED2_ALERT_XFF_EXTRADATA ) {
aun - > xff_flags = UNIFIED2_ALERT_XFF_EXTRADATA ;
if ( inet_pton ( AF_INET , buffer , aun - > xff_ip ) = = 1 ) {
aun - > xff_flags | = UNIFIED2_ALERT_XFF_IPV4 ;
} else if ( inet_pton ( AF_INET6 , buffer , aun - > xff_ip ) = = 1 ) {
aun - > xff_flags | = UNIFIED2_ALERT_XFF_IPV6 ;
} else if ( inet_pton ( AF_INET6 , buffer , aun - > xff_ip ) = = 1 ) {
if ( PKT_IS_IPV6 ( p ) ) {
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV6 | UNIFIED2_ALERT_XFF_OVERWRITE ) ;
} else {
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV6 | UNIFIED2_ALERT_XFF_EXTRADATA ) ;
}
}
}
@ -436,8 +442,6 @@ TmEcode Unified2Alert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq, Pa
FLOWLOCK_UNLOCK ( p - > flow ) ;
}
int ret = 0 ;
if ( PKT_IS_IPV4 ( p ) ) {
ret = Unified2IPv4TypeAlert ( t , p , data , pq ) ;
} else if ( PKT_IS_IPV6 ( p ) ) {
@ -962,6 +966,31 @@ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq
if ( unlikely ( pa - > s = = NULL ) )
continue ;
if ( ( aun - > unified2alert_ctx - > xff_mode & UNIFIED2_ALERT_XFF_EXTRADATA ) & & p - > flow ! = NULL ) {
FLOWLOCK_RDLOCK ( p - > flow ) ;
if ( AppLayerGetProtoFromPacket ( p ) = = ALPROTO_HTTP ) {
char buffer [ UNIFIED2_ALERT_XFF_MAXLEN ] ;
int have_xff_ip = 0 ;
if ( pa - > flags & PACKET_ALERT_FLAG_TX ) {
have_xff_ip = GetXFFIPFromTx ( p , pa - > tx_id , aun - > unified2alert_ctx - > xff_header , buffer , UNIFIED2_ALERT_XFF_MAXLEN ) ;
} else {
have_xff_ip = GetXFFIP ( p , aun - > unified2alert_ctx - > xff_header , buffer , UNIFIED2_ALERT_XFF_MAXLEN ) ;
}
if ( have_xff_ip ) {
memset ( aun - > xff_ip , 0 , 4 * sizeof ( uint32_t ) ) ;
if ( inet_pton ( AF_INET , buffer , aun - > xff_ip ) = = 1 ) {
SCLogDebug ( " valid ipv4 xff, setting flag " ) ;
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV4 | UNIFIED2_ALERT_XFF_EXTRADATA ) ;
} else if ( inet_pton ( AF_INET6 , buffer , aun - > xff_ip ) = = 1 ) {
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV6 | UNIFIED2_ALERT_XFF_EXTRADATA ) ;
}
}
}
FLOWLOCK_UNLOCK ( p - > flow ) ;
}
/* reset length and offset */
aun - > offset = offset ;
aun - > length = length ;
@ -1111,6 +1140,32 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p
if ( unlikely ( pa - > s = = NULL ) )
continue ;
if ( ( aun - > unified2alert_ctx - > xff_mode & UNIFIED2_ALERT_XFF_EXTRADATA ) & & p - > flow ! = NULL ) {
FLOWLOCK_RDLOCK ( p - > flow ) ;
if ( AppLayerGetProtoFromPacket ( p ) = = ALPROTO_HTTP ) {
char buffer [ UNIFIED2_ALERT_XFF_MAXLEN ] ;
int have_xff_ip = 0 ;
if ( pa - > flags & PACKET_ALERT_FLAG_TX ) {
have_xff_ip = GetXFFIPFromTx ( p , pa - > tx_id , aun - > unified2alert_ctx - > xff_header , buffer , UNIFIED2_ALERT_XFF_MAXLEN ) ;
} else {
have_xff_ip = GetXFFIP ( p , aun - > unified2alert_ctx - > xff_header , buffer , UNIFIED2_ALERT_XFF_MAXLEN ) ;
}
if ( have_xff_ip ) {
SCLogDebug ( " buffer %s " , buffer ) ;
memset ( aun - > xff_ip , 0 , 4 * sizeof ( uint32_t ) ) ;
if ( inet_pton ( AF_INET , buffer , aun - > xff_ip ) = = 1 ) {
SCLogDebug ( " valid ipv4 xff, setting flags %s " , buffer ) ;
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV4 | UNIFIED2_ALERT_XFF_EXTRADATA ) ;
} else if ( inet_pton ( AF_INET6 , buffer , aun - > xff_ip ) = = 1 ) {
aun - > xff_flags = ( UNIFIED2_ALERT_XFF_IPV6 | UNIFIED2_ALERT_XFF_EXTRADATA ) ;
}
}
}
FLOWLOCK_UNLOCK ( p - > flow ) ;
}
/* reset length and offset */
aun - > offset = offset ;
aun - > length = length ;