u_int32_t server_stats_hitcount_ipv4(SERVER_STATS *ssp, u_int8_t ip_proto, u_int32_t address, u_int16_t port) { SERVER_KEY *kp = &s_key; u_int32_t *hitcountp; #ifdef DEBUG u_int32_t hostaddress = ntohl(address); #endif /* DEBUG */ /* OK, IPSETs are acting in HOST ORDER */ FLOWASSERT(ipset_contains(ssp->ipv4_watch, &hostaddress, IPV4_FAMILY)); /* make a key */ kp->address = address; kp->port = port; kp->protocol = ip_proto; hitcountp = (u_int32_t *) sfxhash_find(ssp->ipv4_table, kp); if(hitcountp != NULL) { return *hitcountp; } return 0; }
int server_stats_add_ipv4(SERVER_STATS *ssp, u_int8_t ip_proto, u_int32_t address, u_int16_t port, u_int32_t *retcount) { SERVER_KEY *kp = &s_key; u_int32_t one = 1; u_int32_t *hitcountp = NULL; int ret; #ifdef DEBUG u_int32_t hostaddress = ntohl(address); #endif /* DEBUG */ if(ssp == NULL || retcount == NULL) return FLOW_ENULL; /* calls to this subsystem should only be made if we are really watching this. */ FLOWASSERT(ipset_contains(ssp->ipv4_watch, &hostaddress, IPV4_FAMILY)); /* make the key */ kp->address = address; kp->port = port; kp->protocol = ip_proto; /* find the key, add 1 to it or add a new node to the table */ ret = sfxhash_add(ssp->ipv4_table, kp, &one); switch(ret) { case SFXHASH_NOMEM: /* NOMEM means that we would add it if we could but we're * hard-core out of space. So, just assume we added it. */ case SFXHASH_OK: *retcount = 1; break; case SFXHASH_INTABLE: hitcountp = (u_int32_t *) sfxhash_mru(ssp->ipv4_table); /* never let us wrap around to less hits */ if(!hitcountp) { /* this is an odd error! */ return FLOW_BADJUJU; } else { if((*hitcountp) < SERVER_STATS_MAX_HITCOUNT) { (*hitcountp)++; } } break; } return FLOW_SUCCESS; }
/** * Determine if server stats is enabled for this particular IP * address. * * @param trackerp portscan tracker to inquire * * @return FLOW_SUCCESS if the server watchnet stuff is enabled */ int flowps_server_watch(PS_TRACKER *trackerp, u_int32_t address) { FLOWASSERT(trackerp != NULL); if(trackerp->config.server_watchnet_ipv4 == NULL) return FLOW_DISABLED; if(server_stats_contains(&trackerp->server_stats,address) == FLOW_SUCCESS) return FLOW_SUCCESS; /* finally fail */ return FLOW_DISABLED; }
/** * Evaluate the score on an entry, generating alerts if needed. * * @param pstp portscan tracker * @param sep score entry * @param score score determined for this flow * @param tr_pos what type of connection the current one is * @param alert_once alert only on the first one we find * @param alert_flags what type of alerts should we generate * * @return FLOW_SUCCESS on success */ int flowps_score_entry(PS_TRACKER *pstp, SCORE_ENTRY *sep, int score, TRACKER_POSITION tr_pos, int alert_once, u_int32_t *alert_flags) { /* @todo - evaluate the score for the node before we evaluate the expiration on a sliding time window */ if(!pstp || !sep || !alert_flags) { return FLOW_ENULL; } *alert_flags = 0; if(alert_once == 0) { /* if our score entry flags ever get set to 0, reset the alert * flags */ flowps_reset_alert_flags(ALERT_FIXED_TALKER, &sep->flags, &sep->fixed_talker.score); flowps_reset_alert_flags(ALERT_SLIDING_TALKER, &sep->flags, &sep->sliding_talker.score); flowps_reset_alert_flags(ALERT_FIXED_SCANNER, &sep->flags, &sep->fixed_scanner.score); flowps_reset_alert_flags(ALERT_SLIDING_SCANNER, &sep->flags, &sep->sliding_scanner.score); } FLOWASSERT((tr_pos == TRACKER_SCANNER) || (tr_pos == TRACKER_ACTIVE)); switch(tr_pos) { case TRACKER_SCANNER: sep->fixed_scanner.score += score; sep->sliding_scanner.score += score; /* talking thresholds increment even if this is a "scanner" * connection */ break; case TRACKER_ACTIVE: sep->fixed_talker.score += score; sep->sliding_talker.score += score; break; } /* done resetting the scores, now check the thresholds */ if(pstp->config.limit_talker.fixed && pstp->config.limit_talker.fixed <= sep->fixed_talker.score) { *alert_flags |= ALERT_FIXED_TALKER; } if(pstp->config.limit_talker.sliding && pstp->config.limit_talker.sliding <= sep->sliding_talker.score) { *alert_flags |= ALERT_SLIDING_TALKER; } if(pstp->config.limit_scanner.fixed && pstp->config.limit_scanner.fixed <= sep->fixed_scanner.score) { *alert_flags |= ALERT_FIXED_SCANNER; } if(pstp->config.limit_scanner.sliding && pstp->config.limit_scanner.sliding <= sep->sliding_scanner.score) { *alert_flags |= ALERT_SLIDING_SCANNER; } /* ** This logic will only give us alerts for the ones that have not ** already gone off for this score entry. */ if(alert_once) { *alert_flags &= ~sep->flags; } return FLOW_SUCCESS; }