@ -3224,137 +3224,148 @@ error:
int CreateGroupedPortListCmpCnt ( DetectPort * a , DetectPort * b )
{
if ( a - > sh - > sig_cnt > b - > sh - > sig_cnt )
if ( a - > sh - > sig_cnt > b - > sh - > sig_cnt ) {
SCLogDebug ( " pg %u:%u %u > %u:%u %u " ,
a - > port , a - > port2 , a - > sh - > sig_cnt ,
b - > port , b - > port2 , b - > sh - > sig_cnt ) ;
return 1 ;
}
return 0 ;
}
/** \internal
* \ brief Create a list of DetectPort objects sorted based on CompareFunc ' s
* logic .
*
* List can limit the number of groups . In this case an extra " join " group
* is created that contains the sigs belonging to that . It ' s * appended * to
* the list , meaning that if the list is walked linearly it ' s found last .
* The joingr is meant to be a catch all .
*
*/
int CreateGroupedPortList ( DetectEngineCtx * de_ctx , DetectPort * port_list , DetectPort * * newhead , uint32_t unique_groups , int ( * CompareFunc ) ( DetectPort * , DetectPort * ) , uint32_t max_idx )
{
DetectPort * tmplist = NULL , * tmplist2 = NULL , * joingr = NULL ;
DetectPort * tmplist = NULL , * joingr = NULL ;
char insert = 0 ;
DetectPort * gr , * next_gr ;
uint32_t groups = 0 ;
DetectPort * list ;
/* insert the addresses into the tmplist, where it will
* be sorted descending on ' cnt ' . */
for ( list = port_list ; list ! = NULL ; list = list - > next ) {
gr = ( DetectPort * ) list ;
/* insert the addresses into the tmplist, where it will
* be sorted descending on ' cnt ' and on wehther a group
* is whitelisted . */
SCLogDebug ( " hash list gr %p " , gr ) ;
DetectPortPrint ( gr ) ;
SigGroupHeadSetSigCnt ( gr - > sh , max_idx ) ;
DetectPort * oldhead = port_list ;
while ( oldhead ) {
/* take the top of the list */
list = oldhead ;
oldhead = oldhead - > next ;
list - > next = NULL ;
groups + + ;
/* alloc a copy */
DetectPort * newtmp = DetectPortCopySingle ( de_ctx , gr ) ;
if ( newtmp = = NULL ) {
goto error ;
}
SigGroupHeadSetSigCnt ( newtmp - > sh , max_idx ) ;
SigGroupHeadSetSigCnt ( list - > sh , max_idx ) ;
/* insert it */
DetectPort * tmpgr = tmplist , * prevtmpgr = NULL ;
if ( tmplist = = NULL ) {
/* empty list, set head */
tmplist = newtmp ;
tmplist = list ;
} else {
/* look for the place to insert */
for ( ; tmpgr ! = NULL & & ! insert ; tmpgr = tmpgr - > next ) {
if ( CompareFunc ( gr, tmpgr ) ) {
for ( ; tmpgr ! = NULL & & ! insert ; tmpgr = tmpgr - > next ) {
if ( CompareFunc ( list, tmpgr ) = = 1 ) {
if ( tmpgr = = tmplist ) {
newtmp - > next = tmplist ;
tmplist = newtmp ;
list - > next = tmplist ;
tmplist = list ;
SCLogDebug ( " new list top: %u:%u " , tmplist - > port , tmplist - > port2 ) ;
} else {
newtmp - > next = prevtmpgr - > next ;
prevtmpgr - > next = newtmp ;
list - > next = prevtmpgr - > next ;
prevtmpgr - > next = list ;
}
insert = 1 ;
break ;
}
prevtmpgr = tmpgr ;
}
if ( insert = = 0 ) {
newtmp - > next = NULL ;
prevtmpgr - > next = newtmp ;
list - > next = NULL ;
prevtmpgr - > next = list ;
}
insert = 0 ;
}
}
uint32_t i = unique_groups ;
if ( i = = 0 )
i = groups ;
uint32_t left = unique_groups ;
if ( left = = 0 )
left = groups ;
/* create another list: take the port groups from above
* and add them to the 2 nd list until we have met our
* count . The rest is added to the ' join ' group . */
DetectPort * tmplist2 = NULL , * tmplist2_tail = NULL ;
DetectPort * gr , * next_gr ;
for ( gr = tmplist ; gr ! = NULL ; ) {
SCLogDebug ( " temp list gr %p " , gr ) ;
next_gr = gr - > next ;
SCLogDebug ( " temp list gr %p %u:%u " , gr , gr - > port , gr - > port2 ) ;
DetectPortPrint ( gr ) ;
if ( i = = 0 ) {
/* if we've set up all the unique groups, add the rest to the
* catch - all joingr */
if ( left = = 0 ) {
if ( joingr = = NULL ) {
joingr = DetectPortCopySingle ( de_ctx , gr ) ;
DetectPortParse ( de_ctx , & joingr , " 0:65535 " ) ;
if ( joingr = = NULL ) {
goto error ;
}
} else {
DetectPortJoin ( de_ctx , joingr , gr ) ;
SCLogDebug ( " joingr => %u-%u " , joingr - > port , joingr - > port2 ) ;
joingr - > next = NULL ;
}
SigGroupHeadCopySigs ( de_ctx , gr - > sh , & joingr - > sh ) ;
/* when a group's sigs are added to the joingr, we can free it */
gr - > next = NULL ;
DetectPortFree ( gr ) ;
gr = NULL ;
/* append */
} else {
DetectPort * newtmp = DetectPortCopySingle ( de_ctx , gr ) ;
if ( newtmp = = NULL ) {
goto error ;
}
gr - > next = NULL ;
if ( tmplist2 = = NULL ) {
tmplist2 = newtmp ;
tmplist2 = gr ;
tmplist2_tail = gr ;
} else {
new tmp- > next = tmplist2 ;
tmplist2 = newtmp ;
tmplist2_tail - > next = gr ;
tmplist2 _tail = gr ;
}
}
if ( i ) i - - ;
next_gr = gr - > next ;
gr - > next = NULL ;
DetectPortFree ( gr ) ;
gr = next_gr ;
}
/* we now have a tmplist2 containing the 'unique' groups and
* possibly a joingr that covers the rest . Now build the newhead
* that we will pass back to the caller .
*
* Start with inserting the unique groups */
for ( gr = tmplist2 ; gr ! = NULL ; ) {
SCLogDebug ( " temp list2 gr %p " , gr ) ;
DetectPortPrint ( gr ) ;
DetectPort * newtmp = DetectPortCopySingle ( de_ctx , gr ) ;
if ( newtmp = = NULL ) {
goto error ;
}
int r = DetectPortInsert ( de_ctx , newhead , newtmp ) ;
BUG_ON ( r = = - 1 ) ;
if ( left > 0 )
left - - ;
next_gr = gr - > next ;
gr - > next = NULL ;
DetectPortFree ( gr ) ;
gr = next_gr ;
}
DetectPortPrintList ( * newhead ) ;
/* if present, insert the joingr that covers the rest */
/* if present, append the joingr that covers the rest */
if ( joingr ! = NULL ) {
SCLogDebug ( " inserting joingr %p " , joingr ) ;
DetectPortInsert ( de_ctx , newhead , joingr ) ;
SCLogDebug ( " appending joingr %p %u:%u " , joingr , joingr - > port , joingr - > port2 ) ;
if ( tmplist2 = = NULL ) {
tmplist2 = joingr ;
tmplist2_tail = joingr ;
} else {
tmplist2_tail - > next = joingr ;
tmplist2_tail = joingr ;
}
} else {
SCLogDebug ( " no joingr " ) ;
}
/* pass back our new list to the caller */
* newhead = tmplist2 ;
DetectPortPrintList ( * newhead ) ;
return 0 ;
error :
return - 1 ;