⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flowps.c

📁 入侵检测SNORT.最近更新的基于网络检测的IDS.希望能给大家带来方便.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: *//**************************************************************************** * * Copyright (C) 2003-2008 Sourcefire, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as * published by the Free Software Foundation.  You may not use, modify or * distribute this program under any other version of the GNU General * Public License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ****************************************************************************/ #ifdef HAVE_CONFIG_H#include "config.h"#endif#include "flowps.h"#include "scoreboard.h"#include "unique_tracker.h"#include "server_stats.h"#include "packet_time.h"#include "util_net.h"/* local copy of these tcp flags */#ifndef TH_FIN#define TH_FIN  0x01#define TH_SYN  0x02#define TH_RST  0x04#define TH_PUSH 0x08#define TH_ACK  0x10#define TH_URG  0x20#define TH_RES2 0x40#define TH_RES1 0x80#endif /* TH_FIN */#define FLOWPS_NC 1000000 /* number of rows to use for each scan table */static int s_debug = 0;static int s_enabled = 0;/**  * Setup a SCORE_THRESHOLD object. * * This contains the limits and window sizes that will be used each * time we evaluate a SCORE_ENTRY from one of the scoreboards. *  * @param thr pointer to the threshold to initialize * @param fixed_size the time window for fixed scale * @param fixed_limit the score limit to alert on * @param sliding_size the sliding time window initial size * @param sliding_limit score limit to alert on * @param window_scale what to multiple the sliding size on each "hit" *  * @return FLOW_SUCCESS on success */int flowps_mkthreshold(SCORE_THRESHOLD *thr,                       int fixed_size, u_int32_t fixed_limit,                       int sliding_size, u_int32_t sliding_limit,                       float window_scale){    if(!thr)        return FLOW_ENULL;        if(fixed_size < 0)        fixed_size = 0;    if(sliding_size < 0)        sliding_size = 0;        thr->fixed_size   = fixed_size;    thr->sliding_size = sliding_size;    thr->window_scale = window_scale;    thr->fixed        = fixed_limit;    thr->sliding      = sliding_limit;    return FLOW_SUCCESS;}/**  * Initialize the configuration structure and set everything to 0 *  * @param configp config to set *  * @return FLOW_SUCCESS on success */int flowps_mkconfig(PS_CONFIG *configp,                    int sb_memcap_talker,                    int sb_rows_talker,                    int sb_memcap_scanner,                    int sb_rows_scanner,                    int ut_memcap,                    int ut_rows,                    int server_memcap,                    int server_rows,                    int server_learning_time,                    int tcp_penalties,                    u_int32_t server_ignore_limit,                    u_int32_t server_scanner_limit,                    int base_score,                    int alert_once,                    FLOWPS_OUTPUT output_mode){    if(!configp)        return FLOW_ENULL;    memset(configp, 0, sizeof(PS_CONFIG));               configp->sb_memcap_total   = sb_memcap_scanner + sb_memcap_talker;    configp->sb_memcap_scanner = sb_memcap_scanner;    configp->sb_memcap_talker  = sb_memcap_talker;    configp->sb_rows_talker    = sb_rows_talker;    configp->sb_rows_scanner   = sb_rows_scanner;            configp->tcp_penalties = tcp_penalties;    configp->ut_memcap            = ut_memcap;    configp->ut_rows              = ut_rows;        configp->server_memcap        = server_memcap;    configp->server_rows          = server_rows;    configp->server_learning_time = server_learning_time;    configp->server_ignore_limit  = server_ignore_limit;    configp->server_scanner_limit = server_scanner_limit;    configp->base_score           = base_score;    configp->alert_once           = alert_once;    configp->output_mode          = output_mode;    configp->dumpall              = 0;    return FLOW_SUCCESS;}/**  * Determine if the server stats feature is enabled *  * @param trackerp portscan tracker *  * @return FLOW_SUCCESS if server_stats is enabled */int flowps_server_stats_enabled(PS_TRACKER *trackerp){    if(trackerp->config.server_watchnet_ipv4)        return FLOW_SUCCESS;        return FLOW_DISABLED;}/**  * 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 == NULL)        return FLOW_DISABLED;            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;}/**  * initialize the Portscan Tracker. * * This takes several arguments, all, on the PS_CONFIG structure. *  * @param trackerp tracker object to initialize * @param configp well-formed configuration to initialize this object *  * @return FLOW_SUCCESS on success */int flowps_init(PS_TRACKER *trackerp, PS_CONFIG *configp){    int ret;        if(!trackerp || !configp)        return FLOW_ENULL;    /* we should validate this threshold object somewhat */    memcpy(&trackerp->config, configp, sizeof(PS_CONFIG));        ret = scoreboard_init(&trackerp->table_active,            /* table */                          "Active Talkers",                   /* description */                          TRACKER_ACTIVE,                     /* position */                          trackerp->config.sb_rows_talker,    /* node count */                          trackerp->config.sb_memcap_talker); /* memcap */    if(ret != FLOW_SUCCESS)    {        return ret;    }        ret = scoreboard_init(&trackerp->table_scanner,            /* table */                          "Portscanners",                      /* description */                          TRACKER_SCANNER,                     /* position */                          trackerp->config.sb_rows_scanner,    /* node count */                          trackerp->config.sb_memcap_scanner); /* memcap */    if(ret != FLOW_SUCCESS)    {        scoreboard_destroy(&trackerp->table_active);        return ret;    }    /* setup the unique talkers table */    ret = ut_init(&trackerp->unique_tracker,trackerp->config.ut_rows, trackerp->config.ut_memcap);    if(ret != FLOW_SUCCESS)    {        scoreboard_destroy(&trackerp->table_active);        scoreboard_destroy(&trackerp->table_scanner);        return ret;    }    /* the watchnet stuff is optional */    if(flowps_server_stats_enabled(trackerp) == FLOW_SUCCESS)    {        ret = server_stats_init(&trackerp->server_stats,                                trackerp->config.server_watchnet_ipv4,                                trackerp->config.server_rows,                                trackerp->config.server_memcap);        if(ret != FLOW_SUCCESS)        {            scoreboard_destroy(&trackerp->table_active);            scoreboard_destroy(&trackerp->table_scanner);            ut_destroy(&trackerp->unique_tracker);            return ret;        }    }        s_enabled = 1;        return FLOW_SUCCESS;}int flowps_destroy(PS_TRACKER *trackerp){    if(!trackerp)        return FLOW_ENULL;    scoreboard_destroy(&trackerp->table_scanner);    scoreboard_destroy(&trackerp->table_active);    ut_destroy(&trackerp->unique_tracker);        return FLOW_SUCCESS;}/**  * Reset a single flag in the alert_flags entry if the score is 0 *  * @param type flag to reset * @param alert_flags flag entry * @param score score to reset */static INLINE void flowps_reset_alert_flags(u_int32_t type,                                            u_int32_t *alert_flags,                                            u_int32_t *score){    if(((*alert_flags) & type))    {        *alert_flags &= ~type;        *score = 0;    }}/**  * 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;    }/**  * find the trackers in the table * * Currently, it first looks it up in the active table and then the * scanner table *  * @param trackerp tracker to search * @param address key to search for * @param sepp where to place the results *  * @return FLOW_SUCCESS on sucess and sets sepp */int flowps_find_entry(PS_TRACKER *trackerp, u_int32_t *address, SCORE_ENTRY **sepp){    int ret;        if(!trackerp || !sepp || !address)    {        return FLOW_ENULL;    }    ret = scoreboard_find(&trackerp->table_active, address, sepp);        if(ret == FLOW_NOTFOUND)    {        // flow_printf(stdout, "address was not found :(");        /* the find failed -- look it up in the         * scanner table */        ret = scoreboard_find(&trackerp->table_scanner, address, sepp);    }    return ret;}/**  * Register a new node in the portscan tracker. * * This does not enforce that a node can only be in one table at a * time to avoid the 2 extra searching operations.  All uses of this * should be done after performing a find to make sure the trackers * do not already exist. *  * @param trackerp portscan tracker  * @param position where to place this node * @param address the address for the key * @param sepp score entry return information *  * @return FLOW_SUCCESS on success * * @retval FLOW_ENULL null arguments passed * @retval FLOW_SUCESS sucessfull added * @retval FLOW_EINVALID already in table * @retval FLOW_ENOMEM out of memory */int flowps_add_entry(PS_TRACKER *trackerp,                      TRACKER_POSITION position,                      u_int32_t *address,                      SCORE_ENTRY **sepp){    int ret;        if(position == TRACKER_ACTIVE)    {        ret = scoreboard_add(&trackerp->table_active, address, sepp);    }    else    {        ret = scoreboard_add(&trackerp->table_scanner, address, sepp);    }    if(ret == FLOW_SUCCESS)    {        (*sepp)->position = position;    }            return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -