@ -327,6 +327,9 @@ typedef struct AFPThreadVars_
int promisc ;
int promisc ;
/* bitmask of ignored ssl_pkttypes */
uint32_t pkttype_filter_mask ;
int down_count ;
int down_count ;
uint16_t cluster_id ;
uint16_t cluster_id ;
@ -853,6 +856,25 @@ static inline int AFPReadFromRingWaitForPacket(AFPThreadVars *ptv)
return AFP_READ_OK ;
return AFP_READ_OK ;
}
}
/**
* \ brief AF packet frame ignore logic
*
* Given a sockaddr_ll of a frame , use the pkttype_filter_mask to decide if the
* frame should be ignored . Protect from undefined behavior if there ' s ever
* a sll_pkttype that would shift by too much . At this point , only outgoing
* packets ( 4 ) are ignored . The highest value in if_linux . h is PACKET_KERNEL ( 7 ) ,
* this extra check is being overly cautious .
*
* \ retval true if the frame should be ignored
*/
static inline bool AFPShouldIgnoreFrame ( AFPThreadVars * ptv , const struct sockaddr_ll * sll )
{
if ( unlikely ( sll - > sll_pkttype > 31 ) )
return false ;
return ( ptv - > pkttype_filter_mask & BIT_U32 ( sll - > sll_pkttype ) ) ! = 0 ;
}
/**
/**
* \ brief AF packet read function for ring
* \ brief AF packet read function for ring
*
*
@ -898,6 +920,12 @@ static int AFPReadFromRing(AFPThreadVars *ptv)
goto next_frame ;
goto next_frame ;
}
}
const struct sockaddr_ll * sll =
( const struct sockaddr_ll * ) ( ( uint8_t * ) h . h2 +
TPACKET_ALIGN ( sizeof ( struct tpacket2_hdr ) ) ) ;
if ( unlikely ( AFPShouldIgnoreFrame ( ptv , sll ) ) )
goto next_frame ;
Packet * p = PacketGetFromQueueOrAlloc ( ) ;
Packet * p = PacketGetFromQueueOrAlloc ( ) ;
if ( p = = NULL ) {
if ( p = = NULL ) {
return AFPSuriFailure ( ptv , h ) ;
return AFPSuriFailure ( ptv , h ) ;
@ -990,6 +1018,12 @@ static inline int AFPWalkBlock(AFPThreadVars *ptv, struct tpacket_block_desc *pb
uint8_t * ppd = ( uint8_t * ) pbd + pbd - > hdr . bh1 . offset_to_first_pkt ;
uint8_t * ppd = ( uint8_t * ) pbd + pbd - > hdr . bh1 . offset_to_first_pkt ;
for ( int i = 0 ; i < num_pkts ; + + i ) {
for ( int i = 0 ; i < num_pkts ; + + i ) {
const struct sockaddr_ll * sll =
( const struct sockaddr_ll * ) ( ppd + TPACKET_ALIGN ( sizeof ( struct tpacket3_hdr ) ) ) ;
if ( unlikely ( AFPShouldIgnoreFrame ( ptv , sll ) ) ) {
ppd = ppd + ( ( struct tpacket3_hdr * ) ppd ) - > tp_next_offset ;
continue ;
}
int ret = AFPParsePacketV3 ( ptv , pbd , ( struct tpacket3_hdr * ) ppd ) ;
int ret = AFPParsePacketV3 ( ptv , pbd , ( struct tpacket3_hdr * ) ppd ) ;
switch ( ret ) {
switch ( ret ) {
case AFP_READ_OK :
case AFP_READ_OK :
@ -1877,6 +1911,10 @@ static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose)
goto socket_err ;
goto socket_err ;
}
}
/* ignore outgoing packets on loopback interfaces */
if ( if_flags & IFF_LOOPBACK )
ptv - > pkttype_filter_mask | = BIT_U32 ( PACKET_OUTGOING ) ;
if ( ptv - > promisc ! = 0 ) {
if ( ptv - > promisc ! = 0 ) {
/* Force promiscuous mode */
/* Force promiscuous mode */
memset ( & sock_params , 0 , sizeof ( sock_params ) ) ;
memset ( & sock_params , 0 , sizeof ( sock_params ) ) ;