📄 sfportobject.c
字号:
ponew = posnew; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"*** final - using small rule group only \n");); } else if( nlarge ) { /* * The large rule group port obejct is already set to ponew */ } return ponew;}/* * * * mhash * mhashx */int PortTableCompileMergePortObjects( PortTable * p ){ SF_LNODE * lpos; SFGHASH * mhash; SFGHASH * mhashx; SFGHASH_NODE * node; int id = PO_INIT_ID; static PortObject * pol[SFPO_MAX_LPORTS]; // TODO: dynamically allocate int pol_cnt; char * parray=0; int i; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"***\n***Merging PortObjects->PortObjects2\n***\n");); /* Create a Merged Port Object Table - hash by ports */ mhash = sfghash_new(PO_HASH_TBL_ROWS, sizeof(PortObject *), 0 /*userkeys-no*/, 0 /*free data-don't*/); if( !mhash ) return -1; /* Setup hashing function and key comparison function */ sfhashfcn_set_keyops( mhash->sfhashfcn, PortObject_hash, PortObject_keycmp ); /* remove randomness TODO: do we have to do this always ???? , different event counts if we don't */ //sfhashfcn_static( mhash->sfhashfcn ); p->pt_mpo_hash = mhash; /* Create a Merged Port Object Table - hash by ports */ mhashx = sfghash_new(PO_HASH_TBL_ROWS, sizeof(plx_t *), 0/*userkeys-no*/, 0/*freedata()-don't*/); if( !mhashx ) return -1; /* Setup hashing function and key comparison function */ sfhashfcn_set_keyops( mhashx->sfhashfcn,plx_hash,plx_keycmp ); /* remove randomness TODO: do we have to do this always ???? , different event counts if we don't */ //sfhashfcn_static( mhashx->sfhashfcn ); p->pt_mpxo_hash = mhashx; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"***\n*** PortList-Merging, Large Rule groups must have %d rules\n",p->pt_lrc);); /* * For each port merge rules from all port objects that touch the port * into an optimal object, that may be shared with other ports. */ for(i=0;i<SFPO_MAX_PORTS;i++) { PortObject * po; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"*** building list of port objects for port[%d] ",i);); /* Build a list of port objects touching port 'i' */ pol_cnt = 0; for(po=sflist_firstpos(p->pt_polist,&lpos); po; po=sflist_nextpos(p->pt_polist,&lpos) ) { if( PortObjectHasPort ( po, i ) ) { if( pol_cnt < SFPO_MAX_LPORTS ) { pol[ pol_cnt++ ] = po; } } } p->pt_port_object[i] = 0; if( !pol_cnt ) continue; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"*** merging list for port[%d] ",i);fflush(stdout);); /* merge the rules into an optimal port obejct */ p->pt_port_object[i] = PortTableCompileMergePortObjectList2( mhash, mhashx, pol, pol_cnt, p->pt_lrc ); if( !p->pt_port_object[i] ) { FatalError(" Could not merge PorObjectList on port %d\n",i); return -1; } /* give the new compiled port object an id of its own */ p->pt_port_object[i]->id = id++; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"\n");fflush(stdout);); } /* * Normalize the Ports so they indicate only the ports that * reference the composite port object */ /* 1st- Setup bitmasks for collecting ports */ for(node=sfghash_findfirst(mhashx); node; node=sfghash_findnext(mhashx) ) { unsigned char * buf; PortObject2 * poa; poa = (PortObject2*)node->data; if( !poa ) continue; poa->bitop = calloc(1,sizeof(BITOP)); if( !poa->bitop) { FatalError("Memory error in PortTableCompile\n"); } buf = calloc(1,8192); if( !buf ) { FatalError("Memory alloc error in PortObjectCompile()\n"); } if( boInitStaticBITOP(poa->bitop,8192,buf) ) { FatalError("BitOp error in PortObjectCompile()\n"); } } /* Count how many ports each final port-object is used on */ for(i=0;i<SFPO_MAX_PORTS;i++) { PortObject2 * poa; poa = p->pt_port_object[i]; if(poa) { poa->port_cnt++; if( poa->bitop ) { if( boSetBit(poa->bitop, (unsigned int) i ) ) { FatalError("BitOp-Set error\n"); } } else { FatalError("NULL po->bitop in po on port %d\n",i); } } } /* get a port array 64K bytes */ parray = calloc(1,8*8192); if(!parray) { FatalError("Memory error in PortTableCompile()\n"); } /* Process Port-Bitop map and print final port-object usage stats */ for(node=sfghash_findfirst(mhashx); node; node=sfghash_findnext(mhashx) ) { SF_LIST * plist; PortObject2 * po; po = (PortObject2*)node->data; if( !po ) { FatalError("MergePortOBject-NormalizePorts -NULL po\n"); } if( !po->port_cnt )/* port object is not used ignore it */ continue; if( !po->bitop ) { //FatalError("MergePortOBject-NormalizePorts -NULL po->bitop\n"); continue; } /* Convert the bitop bits to a char array */ memset(parray,0,8*8192); for(i=0;i<8*8192;i++) { if( boIsBitSet(po->bitop, i ) ) { parray[ i ] = 1; } } /* Release bit buffer for each port object */ if( po->bitop ) { if( po->bitop->pucBitBuffer ) { free( po->bitop->pucBitBuffer ); po->bitop->pucBitBuffer = NULL; } free( po->bitop ); po->bitop=NULL; } /* Build a PortObjectItem list from the char array */ plist = PortObjectItemListFromCharPortArray( parray, 8*8192 ); if( !plist ) { FatalError("MergePortObjects: No PortObjectItems in portobject\n"); } /* free the original list */ sflist_free_all( po->item_list, free ); /* set the new list - htis is a list of port itmes for this port object */ po->item_list = plist; DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"port-object id = %d, port cnt = %d\n",po->id,po->port_cnt);); } if(parray) free(parray); return 0;}/* * * Verify all rules in 'po' list are in 'po2' hash * * return 0 - OK * !0 - a rule in po is not in po2 */static int _po2_include_po_rules( PortObject2 * po2, PortObject * po ){ //SFGHASH_NODE * node; int * pid; int * id; SF_LNODE * rpos; /* get each rule in po */ for(pid=sflist_firstpos(po->rule_list,&rpos); pid; pid=sflist_nextpos(po->rule_list,&rpos) ) { /* find it in po2 */ id =(int*) sfghash_find(po2->rule_hash,pid); /* make sure it's in po2 */ if(!id ) { return 1; /* error */ } } return 0;}/* * Perform a consitency check on the final port+rule objects * * Walk the rules */int PortTableConsistencyCheck( PortTable *p ){ char * parray = 0; SFGHASH_NODE * node; int i; SF_LNODE * pos; SF_LNODE * ipos; PortObject * ipo; PortObject2 * lastpo=0; PortObjectItem * poi; parray = calloc(1,8192*8); if(!parray) { FatalError("Memory eror in PortTableComopile\n"); } /* Make sure each port is only in one composite port object */ for(node=sfghash_findfirst(p->pt_mpo_hash); node; node=sfghash_findnext(p->pt_mpo_hash) ) { PortObject2 * po; po = (PortObject2*)node->data; if( !po ) { FatalError("PortObject Consitency Check failed, hash table problem\n"); } if( !po->port_cnt )/* port object is not used ignore it */ continue; for(i=0;i<SFPO_MAX_PORTS;i++) { if( PortObjectHasPort( (PortObject*)po, i ) ) { if( parray[i] ) { FatalError("PortTableCompile: failed consistency check, multiple objects reference port %d\n",i); } parray[i]=1; } } } if( parray ) free(parray); DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"***\n***Port Table Compiler Consistency Check Phase-I Passed !\n");); /* * This phase checks the Input port object rules/ports against * the composite port objects. * * For each input object * check that each port it reference has all of the rules * referenced to that port in the composit object */ for(ipo=sflist_firstpos(p->pt_polist,&pos); ipo; ipo=sflist_nextpos(p->pt_polist,&pos) ) { /* * for each port in this object get the composite port object * assigned to that port and verify all of the input objects rules * are in the composite object. This verifies all rules are applied * to the originally intended port. */ for(poi=sflist_firstpos(ipo->item_list,&ipos); poi; poi=sflist_nextpos(ipo->item_list,&ipos) ) { switch(poi->type) { case PORT_OBJECT_ANY: /* do nothing */ break; case PORT_OBJECT_PORT: if( _po2_include_po_rules( p->pt_port_object[ poi->lport ], ipo ) ) { FatalError("InputPortObject<->CompositePortObject Consitency Check II failed!\n"); } break; case PORT_OBJECT_RANGE: { for(i=poi->lport;i<=poi->hport;i++) { if( lastpo != p->pt_port_object[ i ] )/* small optimization*/ { if( _po2_include_po_rules( p->pt_port_object[ i ], ipo ) ) { FatalError("InputPortObject<->CompositePortObject Consitency Check II failed!\n"); } lastpo = p->pt_port_object[ i ]; } } } break; } } } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS, "***\n***Port Table Compiler Consistency Check Phase-II Passed !!! - Good to go Houston\n****\n");); return 0; }/** Compile the PortTable * * This builds a set of Port+Rule objects that are in some way an optimal* set of objects to indicate which rules to apply to which ports. Since * these groups are calculated consitecny checking is done witht he finished* objects.*/int PortTableCompile( PortTable * p ){ /* * If not using an optimized Table use the rule_index_map in parser.c */ if( !p->pt_optimize ) { return 0; } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"#PortTableCompile: Compiling Port Array Lists\n");); if( PortTableCompileMergePortObjects( p ) ) { FatalError("Could not create PortArryayLists\n"); return -1; } DEBUG_WRAP(DebugMessage(DEBUG_PORTLISTS,"Done\n");fflush(stdout);); PortTableConsistencyCheck(p); return 0;}static int icompare( const void *arg1, const void *arg2 ){ if( *(int*)arg1 < *(int*)arg2 ) return -1; if( *(int*)arg1 > *(int*)arg2 ) return 1; return 0;}static int * RuleListToSortedArray( SF_LIST * rl ){ SF_LNODE * pos; int * prid; int * ra; int k=0; if( !rl ) return 0; if(!rl->count) return NULL; ra = (int *)SnortAlloc(rl->count * sizeof(int)); for( prid = sflist_firstpos(rl,&pos); prid!= 0 && k < (int)rl->count; prid = sflist_nextpos(rl,&pos) ) { ra[k++] = *prid; } /* sort the array */ qsort(ra,rl->count,sizeof(int),icompare); return ra;}static int * RuleHashToSortedArray( SFGHASH * rh ){ int * prid; int * ra; int k=0; SFGHASH_NODE * node; if( !rh ) return 0; if(!rh->count) return NULL; ra = (int *)SnortAlloc(rh->count * sizeof(int)); for( node = sfghash_findfirst(rh); node != 0 && k < (int)rh->count; node = sfghash_findnext(rh) ) { prid = node->data; if( prid ) { ra[k++] = *prid; } } /* sort the array */ qsort(ra,rh->count,sizeof(int),icompare); return ra;}/* * Print Input Port List */void PortTablePrintInput( PortTable * p ){ PortObject * po; SF_LNODE * pos; LogMessage("*** %d PortObjects in Table\n",p->pt_polist->count); for(po =(PortObject*)sflist_firstpos(p->pt_polist,&pos); po!=0; po =(PortObject*)sflist_nextpos(p->pt_polist,&pos) ) { PortObjectPrint( po ); }}void PortTablePrintInputEx( PortTable * p, void (*print_index_map)(int index) ){ PortObject * po; SF_LNODE * pos; for(po =(PortObject*)sflist_firstpos(p->pt_polist,&pos); po!=0; po =(PortObject*)sflist_nextpos(p->pt_polist,&pos) ) { PortObjectPrintEx( po, print_index_map ); }}/* Prints Compiled Ports/Rules Objects */int PortTablePrintCompiledEx( PortTable * p , void (*print
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -