@ -172,7 +172,8 @@ static SCMutex afpacket_bpf_set_filter_lock = SCMUTEX_INITIALIZER;
enum {
AFP_READ_OK ,
AFP_READ_FAILURE ,
AFP_FAILURE ,
/** Error during treatment by other functions of Suricata */
AFP_SURI_FAILURE ,
AFP_KERNEL_DROP ,
} ;
@ -215,6 +216,7 @@ typedef struct AFPThreadVars_
/* references to packet and drop counters */
uint16_t capture_kernel_packets ;
uint16_t capture_kernel_drops ;
uint16_t capture_errors ;
/* handle state */
uint8_t afp_state ;
@ -594,7 +596,7 @@ static int AFPRead(AFPThreadVars *ptv)
p = PacketGetFromQueueOrAlloc ( ) ;
if ( p = = NULL ) {
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
PKT_SET_SRC ( p , PKT_SRC_WIRE ) ;
@ -620,7 +622,7 @@ static int AFPRead(AFPThreadVars *ptv)
SET_PKT_LEN ( p , caplen + offset ) ;
if ( PacketCopyData ( p , ptv - > data , GET_PKT_LEN ( p ) ) = = - 1 ) {
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
SCLogDebug ( " pktlen: % " PRIu32 " (pkt %p, pkt data %p) " ,
GET_PKT_LEN ( p ) , p , GET_PKT_DATA ( p ) ) ;
@ -660,7 +662,7 @@ static int AFPRead(AFPThreadVars *ptv)
if ( TmThreadsSlotProcessPkt ( ptv - > tv , ptv - > slot , p ) ! = TM_ECODE_OK ) {
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
SCReturnInt ( AFP_READ_OK ) ;
}
@ -824,8 +826,10 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
/* Read packet from ring */
h . raw = ( ( ( union thdr * * ) ptv - > ring_v2 ) [ ptv - > frame_offset ] ) ;
if ( h . raw = = NULL ) {
SCReturnInt ( AFP_FAILURE ) ;
if ( unlikely ( h . raw = = NULL ) ) {
/* Impossible we reach this point in normal condition, so trigger
* a failure in reading */
SCReturnInt ( AFP_READ_FAILURE ) ;
}
if ( ( ! h . h2 - > tp_status ) | | ( h . h2 - > tp_status & TP_STATUS_USER_BUSY ) ) {
@ -863,7 +867,7 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
p = PacketGetFromQueueOrAlloc ( ) ;
if ( p = = NULL ) {
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
PKT_SET_SRC ( p , PKT_SRC_WIRE ) ;
@ -892,7 +896,7 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
if ( ptv - > flags & AFP_ZERO_COPY ) {
if ( PacketSetData ( p , ( unsigned char * ) h . raw + h . h2 - > tp_mac , h . h2 - > tp_snaplen ) = = - 1 ) {
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
} else {
p - > afp_v . relptr = h . raw ;
p - > ReleasePacket = AFPReleasePacket ;
@ -908,8 +912,15 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
}
} else {
if ( PacketCopyData ( p , ( unsigned char * ) h . raw + h . h2 - > tp_mac , h . h2 - > tp_snaplen ) = = - 1 ) {
/* As we can possibly fail to copy the data due to invalid data, let's
* skip this packet and switch to the next one .
*/
h . h2 - > tp_status = TP_STATUS_KERNEL ;
if ( + + ptv - > frame_offset > = ptv - > req . tp_frame_nr ) {
ptv - > frame_offset = 0 ;
}
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_FAILURE ) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
}
/* Timestamp */
@ -951,7 +962,7 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
ptv - > frame_offset = 0 ;
}
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
next_frame :
@ -975,7 +986,7 @@ static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc
{
Packet * p = PacketGetFromQueueOrAlloc ( ) ;
if ( p = = NULL ) {
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
PKT_SET_SRC ( p , PKT_SRC_WIRE ) ;
@ -993,7 +1004,7 @@ static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc
if ( ptv - > flags & AFP_ZERO_COPY ) {
if ( PacketSetData ( p , ( unsigned char * ) ppd + ppd - > tp_mac , ppd - > tp_snaplen ) = = - 1 ) {
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
p - > afp_v . relptr = ppd ;
p - > ReleasePacket = AFPReleasePacketV3 ;
@ -1009,7 +1020,7 @@ static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc
} else {
if ( PacketCopyData ( p , ( unsigned char * ) ppd + ppd - > tp_mac , ppd - > tp_snaplen ) = = - 1 ) {
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
}
/* Timestamp */
@ -1038,7 +1049,7 @@ static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc
if ( TmThreadsSlotProcessPkt ( ptv - > tv , ptv - > slot , p ) ! = TM_ECODE_OK ) {
TmqhOutputPacketpool ( ptv - > tv , p ) ;
SCReturnInt ( AFP_ FAILURE) ;
SCReturnInt ( AFP_ SURI_ FAILURE) ;
}
SCReturnInt ( AFP_READ_OK ) ;
@ -1048,12 +1059,23 @@ static inline int AFPWalkBlock(AFPThreadVars *ptv, struct tpacket_block_desc *pb
{
int num_pkts = pbd - > hdr . bh1 . num_pkts , i ;
uint8_t * ppd ;
int ret = 0 ;
ppd = ( uint8_t * ) pbd + pbd - > hdr . bh1 . offset_to_first_pkt ;
for ( i = 0 ; i < num_pkts ; + + i ) {
if ( unlikely ( AFPParsePacketV3 ( ptv , pbd ,
( struct tpacket3_hdr * ) ppd ) = = AFP_FAILURE ) ) {
SCReturnInt ( AFP_READ_FAILURE ) ;
ret = AFPParsePacketV3 ( ptv , pbd ,
( struct tpacket3_hdr * ) ppd ) ;
switch ( ret ) {
case AFP_READ_OK :
break ;
case AFP_SURI_FAILURE :
/* Internal error but let's just continue and
* treat thenext packet */
break ;
case AFP_READ_FAILURE :
SCReturnInt ( AFP_READ_FAILURE ) ;
default :
SCReturnInt ( ret ) ;
}
ppd = ppd + ( ( struct tpacket3_hdr * ) ppd ) - > tp_next_offset ;
}
@ -1075,6 +1097,7 @@ static int AFPReadFromRingV3(AFPThreadVars *ptv)
{
# ifdef HAVE_TPACKET_V3
struct tpacket_block_desc * pbd ;
int ret = 0 ;
/* Loop till we have packets available */
while ( 1 ) {
@ -1090,9 +1113,10 @@ static int AFPReadFromRingV3(AFPThreadVars *ptv)
SCReturnInt ( AFP_READ_OK ) ;
}
if ( unlikely ( AFPWalkBlock ( ptv , pbd ) ! = AFP_READ_OK ) ) {
ret = AFPWalkBlock ( ptv , pbd ) ;
if ( unlikely ( ret ! = AFP_READ_OK ) ) {
AFPFlushBlock ( pbd ) ;
SCReturnInt ( AFP_READ_FAILURE ) ;
SCReturnInt ( ret ) ;
}
AFPFlushBlock ( pbd ) ;
@ -1496,9 +1520,8 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
ptv - > iface , errno , strerror ( errno ) ) ;
AFPSwitchState ( ptv , AFP_STATE_DOWN ) ;
continue ;
case AFP_FAILURE :
AFPSwitchState ( ptv , AFP_STATE_DOWN ) ;
SCReturnInt ( TM_ECODE_FAILED ) ;
case AFP_SURI_FAILURE :
StatsIncr ( ptv - > tv , ptv - > capture_errors ) ;
break ;
case AFP_KERNEL_DROP :
AFPDumpCounters ( ptv ) ;
@ -2199,6 +2222,8 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
ptv - > tv ) ;
ptv - > capture_kernel_drops = StatsRegisterCounter ( " capture.kernel_drops " ,
ptv - > tv ) ;
ptv - > capture_errors = StatsRegisterCounter ( " capture.errors " ,
ptv - > tv ) ;
# endif
ptv - > copy_mode = afpconfig - > copy_mode ;