int ipset_print( IPSET * ipc ) { char ip_str[80]; PORTRANGE * pr; if( !ipc ) return 0; { IP_PORT * p; printf("IPSET\n"); for( p =(IP_PORT*)sflist_first( &ipc->ip_list ); p!=0; p =(IP_PORT*)sflist_next( &ipc->ip_list ) ) { SnortSnprintf(ip_str, 80, "%s", sfip_to_str(&p->ip)); printf("CIDR BLOCK: %c%s", p->notflag ? '!' : ' ', ip_str); for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { printf(" %d", pr->port_lo); if ( pr->port_hi != pr->port_lo ) printf("-%d", pr->port_hi); } printf("\n"); } } return 0; }
void ipset_free( IPSET * ipc ) { if( ipc ) { if( ipc->family == IPV4_FAMILY ) { CIDRBLOCK *p = (CIDRBLOCK *) sflist_first(&ipc->cidr_list); while ( p ) { sflist_free(&p->portset.port_list); p = (CIDRBLOCK *) sflist_next(&ipc->cidr_list); } } else if( ipc->family == IPV6_FAMILY ) { CIDRBLOCK6 *p = (CIDRBLOCK6 *) sflist_first(&ipc->cidr_list); while ( p ) { sflist_free(&p->portset.port_list); p = (CIDRBLOCK6 *) sflist_next(&ipc->cidr_list); } } sflist_free( &ipc->cidr_list ); free( ipc ); } }
int ipset_contains( IPSET * ipc, sfip_t * ip, void *port) { PORTRANGE *pr; unsigned short portu; IP_PORT * p; if( !ipc ) return 0; if ( port ) portu = *((unsigned short *)port); else portu = 0; for(p =(IP_PORT*)sflist_first( &ipc->ip_list ); p!=0; p =(IP_PORT*)sflist_next( &ipc->ip_list ) ) { if( sfip_contains(&p->ip, ip) == SFIP_CONTAINS) { for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { /* * If the matching IP has a wildcard port (pr->port_hi == 0 ) * or if the ports actually match. */ if ( (pr->port_hi == 0) || (portu >= pr->port_lo && portu <= pr->port_hi) ) { if( p->notflag ) return 0; return 1; } } } } return 0; }
IPSET * ipset_copy( IPSET *ipsp ) { IPSET * newset = ipset_new(); IP_PORT *ip_port; for(ip_port =(IP_PORT*)sflist_first( &ipsp->ip_list ); ip_port !=NULL; ip_port =(IP_PORT*)sflist_next( &ipsp->ip_list ) ) { ipset_add(newset, &ip_port->ip, &ip_port->portset, ip_port->notflag); } return newset; }
IPSET * ipset_copy( IPSET *ipsp ) { int family; IPSET * newset = NULL; CIDRBLOCK *cbp; CIDRBLOCK6 *cbp6; if(ipsp) { family = ipset_family( ipsp ); newset = ipset_new(family) ; if( family == IPV4_FAMILY ) { for(cbp =(CIDRBLOCK*)sflist_first( &ipsp->cidr_list ); cbp !=NULL; cbp =(CIDRBLOCK*)sflist_next( &ipsp->cidr_list ) ) { ipset_add(newset, &cbp->ip, &cbp->mask, &cbp->portset, cbp->notflag, family); } } else { for(cbp6 =(CIDRBLOCK6*)sflist_first( &ipsp->cidr_list ); cbp6 !=NULL; cbp6 =(CIDRBLOCK6*)sflist_next( &ipsp->cidr_list ) ) { ipset_add(newset, &cbp6->ip, &cbp6->mask, &cbp6->portset, cbp6->notflag, family); } } } return newset; }
void ipset_free( IPSET * ipc ) { if (ipc) { IP_PORT *p = (IP_PORT *) sflist_first(&ipc->ip_list); while ( p ) { sflist_static_free_all(&p->portset.port_list, free); p = (IP_PORT *) sflist_next(&ipc->ip_list); } sflist_static_free_all(&ipc->ip_list, free); free( ipc ); } }
static int print_thd_local(ThresholdObjects *thd_objs, PrintFormat type, unsigned* prnMode) { SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; int gen_id; SFGHASH_NODE * item_hash_node; int lcnt=0; tSfPolicyId policyId; for (policyId = 0; policyId < thd_objs->numPoliciesAllocated; policyId++) { for(gen_id=0;gen_id < THD_MAX_GENID ; gen_id++ ) { sfthd_hash = thd_objs->sfthd_array[gen_id]; if( !sfthd_hash ) { continue; } for(item_hash_node = sfghash_findfirst( sfthd_hash ); item_hash_node != 0; item_hash_node = sfghash_findnext( sfthd_hash ) ) { /* Check for any Permanent sig_id objects for this gen_id */ sfthd_item = (THD_ITEM*)item_hash_node->data; if (sfthd_item->policyId != policyId) { continue; } for( sfthd_node = (THD_NODE*)sflist_first(sfthd_item->sfthd_node_list); sfthd_node != 0; sfthd_node = (THD_NODE*)sflist_next(sfthd_item->sfthd_node_list) ) { if (print_thd_node(sfthd_node, type, prnMode) != 0) lcnt++; } } } } if( !lcnt && !*prnMode ) LogMessage("| none\n"); return 0; }
/* A function to print the thresholding objects to stdout. * * @param pContext pointer to global threshold context * @return */ void SFRF_ShowObjects(RateFilterConfig *config) { SFGHASH* genHash; tSFRFSidNode* pSidnode; tSFRFConfigNode* cfgNode; int gid; SFGHASH_NODE* sidHashNode; for ( gid=0;gid < SFRF_MAX_GENID ; gid++ ) { genHash = config->genHash [ gid ]; if ( !genHash ) { continue; } printf("...GEN_ID = %u\n",gid); for ( sidHashNode = sfghash_findfirst( genHash ); sidHashNode != 0; sidHashNode = sfghash_findnext( genHash ) ) { /* Check for any Permanent sid objects for this gid */ pSidnode = (tSFRFSidNode*)sidHashNode->data; printf(".....GEN_ID = %u, SIG_ID = %u, PolicyId = %u\n",gid, pSidnode->sid, pSidnode->policyId); /* For each permanent thresholding object, test/add/update the thd object */ /* We maintain a list of thd objects for each gid+sid */ /* each object has it's own unique thd_id */ for ( cfgNode = (tSFRFConfigNode*)sflist_first(pSidnode->configNodeList); cfgNode != 0; cfgNode = (tSFRFConfigNode*)sflist_next(pSidnode->configNodeList) ) { printf(".........SFRF_ID =%d\n",cfgNode->tid ); printf(".........tracking =%d\n",cfgNode->tracking); printf(".........count =%u\n",cfgNode->count); printf(".........seconds =%u\n",cfgNode->seconds); } } } }
/* Test a an event against the threshold database. Events without thresholding * objects are automatically loggable. * * @param pContext Threshold table pointer * @param gid Generator Id from the event * @param sid Signature Id from the event * @param sip Event/Packet Src IP address * @param dip Event/Packet Dst IP address * @param curTime Current Event/Packet time * @param op operation of type SFRF_COUNT_OPERATION * * @return -1 if packet is within dos_threshold and therefore action is allowed. * >=0 if packet violates a dos_threshold and therefore new_action should * replace rule action. new_action value is returned. */ int SFRF_TestThreshold( RateFilterConfig *config, unsigned gid, unsigned sid, snort_ip_p sip, snort_ip_p dip, time_t curTime, SFRF_COUNT_OPERATION op ) { SFGHASH *genHash; tSFRFSidNode* pSidNode; tSFRFConfigNode* cfgNode; int newStatus = -1; int status = -1; tSFRFGenHashKey key; tSfPolicyId policy_id = getRuntimePolicy(); #ifdef SFRF_DEBUG printf("--%d-%d-%d: %s() entering\n", 0, gid, sid, __func__); fflush(stdout); #endif if ( gid >= SFRF_MAX_GENID ) return status; /* bogus gid */ // Some events (like 'TCP connection closed' raised by preprocessor may // not have any configured threshold but may impact thresholds for other // events (like 'TCP connection opened' _updateDependentThresholds(config, gid, sid, sip, dip, curTime); /* * Get the hash table for this gid */ genHash = config->genHash [ gid ]; if ( !genHash ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: no hash table entry for gid\n", 0, gid, sid); fflush(stdout); #endif return status; } /* * Check for any Permanent sid objects for this gid */ key.sid = sid; key.policyId = policy_id; pSidNode = (tSFRFSidNode*)sfghash_find( genHash, (void*)&key ); if ( !pSidNode ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: no DOS THD object\n", 0, gid, sid); fflush(stdout); #endif return status; } /* No List of Threshold objects - bail and log it */ if ( !pSidNode->configNodeList ) { #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: No user configuration\n", 0, gid, sid); fflush(stdout); #endif return status; } /* For each permanent thresholding object, test/add/update the config object */ /* We maintain a list of thd objects for each gid+sid */ /* each object has it's own unique thd_id */ for ( cfgNode = (tSFRFConfigNode*)sflist_first(pSidNode->configNodeList); cfgNode != 0; cfgNode = (tSFRFConfigNode*)sflist_next(pSidNode->configNodeList) ) { switch (cfgNode->tracking) { case SFRF_TRACK_BY_SRC: if ( SFRF_AppliesTo(cfgNode, sip) ) { newStatus = SFRF_TestObject(cfgNode, sip, curTime, op); } break; case SFRF_TRACK_BY_DST: if ( SFRF_AppliesTo(cfgNode, dip) ) { newStatus = SFRF_TestObject(cfgNode, dip, curTime, op); } break; case SFRF_TRACK_BY_RULE: { snort_ip cleared; IP_CLEAR(cleared); newStatus = SFRF_TestObject(cfgNode, IP_ARG(cleared), curTime, op); } break; default: // error case break; } #ifdef SFRF_DEBUG printf("--SFRF_DEBUG: %d-%d-%d: Time %d, rate limit blocked: %d\n", cfgNode->tid, gid, sid, (unsigned)curTime, newStatus); fflush(stdout); #endif // rate limit is reached if ( newStatus >= 0 && (status == -1) ) { status = newStatus; } } // rate limit not reached return status; }
int ipset_print( IPSET * ipc ) { char ip_str[80], mask_str[80]; PORTRANGE * pr; if( !ipc ) return 0; if( ipc->family == IPV4_FAMILY ) { CIDRBLOCK * p; printf("IPSET-IPV4\n"); for( p =(CIDRBLOCK*)sflist_first( &ipc->cidr_list ); p!=0; p =(CIDRBLOCK*)sflist_next( &ipc->cidr_list ) ) { ip4_sprintx(ip_str, 80, &p->ip); ip4_sprintx(mask_str,80, &p->mask); if( p->notflag ) printf("CIDR BLOCK: !%s / %s", ip_str,mask_str); else printf("CIDR BLOCK: %s / %s", ip_str,mask_str); for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { printf(" : %d", pr->port_lo); if ( pr->port_hi != pr->port_lo ) printf("-%d", pr->port_hi); } printf("\n"); } } else if( ipc->family == IPV6_FAMILY ) { CIDRBLOCK6 * p; printf("IPSET-IPV6\n"); for(p =(CIDRBLOCK6*)sflist_first( &ipc->cidr_list ); p!=0; p =(CIDRBLOCK6*)sflist_next( &ipc->cidr_list ) ) { ip6_sprintx(ip_str, 80,p->ip); ip6_sprintx(mask_str,80,p->mask); if( p->notflag ) printf("CIDR BLOCK: !%s / %s", ip_str,mask_str); else printf("CIDR BLOCK: %s / %s", ip_str,mask_str); for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { printf(" : %d", pr->port_lo); if ( pr->port_hi != pr->port_lo ) printf("-%d", pr->port_hi); } printf("\n"); } } else return -1; return 0; }
int ipset_contains( IPSET * ipc, void * ip, void *port, int family ) { PORTRANGE *pr; unsigned short portu; if( !ipc ) return 0; if( ipc->family != family ) { return 0; } if ( port ) portu = *((unsigned short *)port); else portu = 0; if( ipc->family == IPV4_FAMILY ) { CIDRBLOCK * p; unsigned * ipu = (unsigned*)ip; for(p =(CIDRBLOCK*)sflist_first( &ipc->cidr_list ); p!=0; p =(CIDRBLOCK*)sflist_next( &ipc->cidr_list ) ) { if( (p->mask & (*ipu)) == p->ip ) { for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { /* * If the matching IP has a wildcard port (pr->port_hi == 0 ) or * if the ports actually match. */ if ( (pr->port_hi == 0) || (portu >= pr->port_lo && portu <= pr->port_hi) ) { if( p->notflag ) return 0; return 1; } } } } } else if( ipc->family == IPV6_FAMILY ) { CIDRBLOCK6 * p; unsigned short * ips = (unsigned short *)ip; unsigned short mip[8]; for(p = (CIDRBLOCK6*)sflist_first( &ipc->cidr_list ); p!= 0; p = (CIDRBLOCK6*)sflist_next( &ipc->cidr_list ) ) { mip[0] = (unsigned short)(p->mask[0] & ips[0]); mip[1] = (unsigned short)(p->mask[1] & ips[1]); mip[2] = (unsigned short)(p->mask[2] & ips[2]); mip[3] = (unsigned short)(p->mask[3] & ips[3]); mip[4] = (unsigned short)(p->mask[4] & ips[4]); mip[5] = (unsigned short)(p->mask[5] & ips[5]); mip[6] = (unsigned short)(p->mask[6] & ips[6]); mip[7] = (unsigned short)(p->mask[7] & ips[7]); if( memcmp(mip,p->ip,IPV6_LEN) == 0 ) { for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list); pr != 0; pr=(PORTRANGE*)sflist_next(&p->portset.port_list) ) { /* * If the caller wants to match any port (portu == 0) or * if the matching IP has a wildcard port (pr->port_hi == 0 ) or * if the ports actually match. */ if ( portu == 0 || pr->port_hi == 0 || (portu >= pr->port_lo && portu <= pr->port_hi) ) { if( p->notflag ) return 0; return 1; } } } } } else return -1; return 0; }
/*! * A function to print the thresholding objects to stdout. * */ int sfthd_show_objects(ThresholdObjects *thd_objs) { SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; int gen_id; SFGHASH_NODE * item_hash_node; tSfPolicyId policyId; for(gen_id=0;gen_id < THD_MAX_GENID ; gen_id++ ) { sfthd_hash = thd_objs->sfthd_array[gen_id]; if (sfthd_hash == NULL) continue; printf("...GEN_ID = %u\n",gen_id); for(item_hash_node = sfghash_findfirst( sfthd_hash ); item_hash_node != 0; item_hash_node = sfghash_findnext( sfthd_hash ) ) { /* Check for any Permanent sig_id objects for this gen_id */ sfthd_item = (THD_ITEM*)item_hash_node->data; printf(".....GEN_ID = %u, SIG_ID = %u, Policy = %u\n",gen_id,sfthd_item->sig_id, sfthd_item->policyId); /* For each permanent thresholding object, test/add/update the thd object */ /* We maintain a list of thd objects for each gen_id+sig_id */ /* each object has it's own unique thd_id */ for( sfthd_node = (THD_NODE*)sflist_first(sfthd_item->sfthd_node_list); sfthd_node != 0; sfthd_node = (THD_NODE*)sflist_next(sfthd_item->sfthd_node_list) ) { printf(".........THD_ID =%d\n",sfthd_node->thd_id ); if( sfthd_node->type == THD_TYPE_SUPPRESS ) printf(".........type =Suppress\n"); if( sfthd_node->type == THD_TYPE_LIMIT ) printf(".........type =Limit\n"); if( sfthd_node->type == THD_TYPE_THRESHOLD ) printf(".........type =Threshold\n"); if( sfthd_node->type == THD_TYPE_BOTH ) printf(".........type =Both\n"); printf(".........tracking=%d\n",sfthd_node->tracking); printf(".........priority=%d\n",sfthd_node->priority); if( sfthd_node->type == THD_TYPE_SUPPRESS ) { printf(".........ip =%s\n", sfip_to_str(&sfthd_node->ip_address)); printf(".........mask =%d\n", sfip_bits(&sfthd_node->ip_address)); printf(".........not_flag=%d\n",sfthd_node->ip_mask); } else { printf(".........count =%d\n",sfthd_node->count); printf(".........seconds =%d\n",sfthd_node->seconds); } } } } return 0; }
/*! * * Test a an event against the threshold database. * Events without thresholding objects are automatically * loggable. * * @param thd Threshold table pointer * @param gen_id Generator Id from the event * @param sig_id Signature Id from the event * @param sip Event/Packet Src IP address * @param dip Event/Packet Dst IP address * @param curtime Current Event/Packet time * * @return integer * @retval 0 : Event is loggable * @retval !0 : Event should not be logged (-1 suppressed, 1 filtered) * */ int sfthd_test_threshold( ThresholdObjects *thd_objs, THD_STRUCT *thd, unsigned gen_id, unsigned sig_id, snort_ip_p sip, snort_ip_p dip, long curtime ) { tThdItemKey key; SFGHASH * sfthd_hash; THD_ITEM * sfthd_item; THD_NODE * sfthd_node; THD_NODE * g_thd_node = NULL; #ifdef THD_DEBUG int cnt; #endif int status=0; tSfPolicyId policy_id = getRuntimePolicy(); if ((thd_objs == NULL) || (thd == NULL)) return 0; #ifdef CRIPPLE return 0; #endif #ifdef THD_DEBUG printf("sfthd_test_threshold...\n");fflush(stdout); #endif if( gen_id >= THD_MAX_GENID ) { #ifdef THD_DEBUG printf("THD_DEBUG: invalid gen_id=%u\n",gen_id); fflush(stdout); #endif return 0; /* bogus gen_id */ } /* * Get the hash table for this gen_id */ sfthd_hash = thd_objs->sfthd_array[gen_id]; if (sfthd_hash == NULL) { #ifdef THD_DEBUG printf("THD_DEBUG: no hash table entry for gen_id=%u\n",gen_id); fflush(stdout); #endif goto global_test; /* return 0; */ /* no threshold objects for this gen_id, log it ! */ } key.sig_id = sig_id; key.policyId = policy_id; /* * Check for any Permanent sig_id objects for this gen_id */ sfthd_item = (THD_ITEM *)sfghash_find(sfthd_hash, (void*)&key); if (sfthd_item == NULL) { #ifdef THD_DEBUG printf("THD_DEBUG: no THD objects for gen_id=%u, sig_id=%u\n",gen_id,sig_id); fflush(stdout); #endif /* no matching permanent sig_id objects so, log it ! */ goto global_test; } /* No List of Threshold objects - bail and log it */ if (sfthd_item->sfthd_node_list == NULL) { goto global_test; } /* For each permanent thresholding object, test/add/update the thd object */ /* We maintain a list of thd objects for each gen_id+sig_id */ /* each object has it's own unique thd_id */ /* Suppression nodes have a very high priority, so they are tested 1st */ #ifdef THD_DEBUG cnt=0; #endif for (sfthd_node = (THD_NODE *)sflist_first(sfthd_item->sfthd_node_list); sfthd_node != NULL; sfthd_node = (THD_NODE *)sflist_next(sfthd_item->sfthd_node_list)) { #ifdef THD_DEBUG cnt++; printf("THD_DEBUG: gen_id=%u sig_id=%u testing thd_id=%d thd_type=%d\n", gen_id, sig_id, sfthd_node->thd_id, sfthd_node->type); fflush(stdout); #endif /* * Test SUPPRESSION and THRESHOLDING */ status = sfthd_test_local(thd->ip_nodes, sfthd_node, sip, dip, curtime ); if( status < 0 ) /* -1 == Don't log and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG: gen_id=%u sig_id=%u, UnLoggable\n\n",gen_id, sig_id,cnt); fflush(stdout); #endif return (status < -1) ? 1 : -1; /* !0 == Don't log it*/ } else if( status == 0 ) /* Log it and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG: gen_id=%u sig_id=%u tested %d THD_NODE's, " "Loggable\n\n",sfthd_item->gen_id, sfthd_item->sig_id,cnt); fflush(stdout); #endif return 0; /* 0 == Log the event */ } /* status > 0 : Log it later but Keep looking * check the next threshold object for a blocking action ... */ } /* * Test for a global threshold object * we're here cause ther were no threshold objects for this gen_id/sig_id pair */ global_test: #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: doing global object test\n"); #endif if (thd_objs->sfthd_garray && thd_objs->sfthd_garray[policy_id]) { g_thd_node = thd_objs->sfthd_garray[policy_id][gen_id]; } if( g_thd_node ) { status = sfthd_test_global( thd->ip_gnodes, g_thd_node, gen_id, sig_id, sip, dip, curtime ); if( status < 0 ) /* -1 == Don't log and stop looking */ { #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: gen_id=%u sig_id=%u THD_NODE's, " "UnLoggable\n\n",gen_id, sig_id); fflush(stdout); #endif return (status < -1) ? 1 : -1; /* !0 == Don't log it*/ } /* Log it ! */ #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: gen_id=%u sig_id=%u THD_NODE's, " "Loggable\n\n",gen_id, sig_id); fflush(stdout); #endif } else { #ifdef THD_DEBUG printf("THD_DEBUG-GLOBAL: no Global THD Object for gen_id=%u, " "sig_id=%u\n\n",gen_id, sig_id); fflush(stdout); #endif } return 0; /* Default: Log it if we did not block the logging action */ }