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

📄 spp_conversation.c

📁 Linux snort-2.4.4源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** 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.*//* $Id$ * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>#ifndef WIN32#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif /* WIN32 */#include <stdlib.h>#include <string.h>#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include "spp_conversation.h"#include "spp_portscan2.h"#include "generators.h"#include "decode.h"#include "plugbase.h"#include "debug.h"#include "util.h"#include "parser.h"#include "mstring.h"#include "log.h"#include "detect.h"#include "event_queue.h"#define CONV_TIMEOUT 120#define CONV_DEFAULT_MAX 65335#define OPT_TIMEOUT "timeout"#define OPT_MAX_CONV "max_conversations"#define OPT_ALLOWED_PROTOS "allowed_ip_protocols"#define OPT_ALERT_BAD_PROTO "alert_odd_protocols"/* if the conversation is going to be stored this way.... * * Only thing this will really have troubles with is traffic between * the same ip*/#define PACKET_FORWARD(a) (*((unsigned int*)&a->iph->ip_dst) > *((unsigned int*)&a->iph->ip_src))#define TRUE 1#define FALSE 0/* This INLINE is conflicting with the INLINE defined in bitop.h. * So, let's just add a little sanity check here. */#ifdef DEBUG    #ifdef INLINE        #undef INLINE    #endif    #define INLINE#else /* DEBUG */    #ifndef INLINE        #define INLINE inline    #endif#endif/*********************** exported Global vars *********************/ConversationData  conv_data;/***********************Function Declaration*************/static void ConvInit(u_char* args);static void ParseConvArgs(u_char* args);static void ConvFunc(Packet* p, void *);static int ConvCompareFunc(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr);static int PruneConvCache(u_int32_t now, int tokill, StateRecord *keeper);static StateRecord* ConvGetSession(Packet* p);static INLINE void FillStateRecord(StateRecord *s, Packet *p);static INLINE void FillConvStats(StateRecord *s, Packet *p);/**************************************** *  Register the preprocessor ****************************************/void SetupConv(void){    RegisterPreprocessor("conversation", ConvInit);    DEBUG_WRAP(DebugMessage(DEBUG_CONVERSATION,                             "Preprocessor: Registering Session\n"););}static void ParseConvArgs(u_char* args){    char **toks;    char **stoks;    char  *index;    int num_toks, s_toks;    int num;    conv_data.timeout = CONV_TIMEOUT;    conv_data.max_convs = CONV_DEFAULT_MAX;        if(args == NULL || *args == '\0')    {        return;    }    /* tokenize the argument list */    toks = mSplit(args, ",", 31, &num_toks, '\\');    /* convert the tokens and place them into the port list       strlen used to easily identify what token - yes a kludge    */    for(num = 0; num < num_toks; num++)    {        index = toks[num];        while(index && isspace((int)*(index)))        {            index++;        }                if(!strncasecmp(OPT_TIMEOUT, index, strlen(OPT_TIMEOUT)))        {            stoks = mSplit(index, " ", 4, &s_toks, 0);            if(s_toks < 2)            {                FatalError("ERROR %s(%d) => No timeout argument to "                           "conversation\n", file_name, file_line);            }            conv_data.timeout = atoi(stoks[1]);            mSplitFree(&stoks, s_toks);        }        else if(!strncasecmp(OPT_MAX_CONV, index,                             strlen(OPT_MAX_CONV)))        {            stoks = mSplit(index, " ", 4, &s_toks, 0);            if(s_toks < 2)            {                FatalError("ERROR %s(%d) => No max_conversations argument "                           "to conversation\n", file_name, file_line);            }            conv_data.max_convs = atoi(stoks[1]);            mSplitFree(&stoks, s_toks);        }        else if(!strncasecmp(OPT_ALLOWED_PROTOS, index,                             strlen(OPT_ALLOWED_PROTOS)))        {            /* need to sit here and parse through what I will allow               and what I won't               defaults to all               you can specify a list of protocols to support            */            char **ports;            int num_ports;            char *port;            int j = 0;            u_int32_t portnum;            for(j = 0;j<256;j++)            {                conv_data.allowed_ip_protocols[j] = 0;            }            ports = mSplit(index, " ", 40, &num_ports, 0);            if(num_ports < 2)            {                FatalError("ERROR %s(%d) => No ip_proto list "                           "to conversation\n", file_name, file_line);            }            j = 1;            while(j < num_ports)            {                port = ports[j];                if(isdigit((int)port[0]))                {                    portnum = atoi(port);                    if(portnum > 255)                    {                        FatalError("ERROR %s(%d) => Bad ip_proto list to "                                   "conversation\n", file_name, file_line);                    }                    conv_data.allowed_ip_protocols[portnum] = 1;                }                else if(!strncasecmp(port, "all", 3))                {                    memset(&conv_data.allowed_ip_protocols, 1, 256);                }                                else                {                    FatalError("ERROR %s(%d) => Bad ip_proto list to "                               "conversation\n", file_name, file_line);                }                j++;            }            mSplitFree(&ports, num_ports);        }        else if(!strncasecmp(OPT_ALERT_BAD_PROTO, index,                             strlen(OPT_ALERT_BAD_PROTO)))        {            conv_data.alert_odd_protocols = 1;        }                else        {            FatalError("ERROR %s(%d) => Unknown argument to spp_conversation "                       "preprocessor: \"%s\"\n",                        file_name, file_line, index);        }    }       mSplitFree(&toks, num_toks);}/**************************************** *  Initialize everything ****************************************/void ConvInit(u_char* args){    int i;    int printall = 1;    char buf[STD_BUF+1];        memset(&conv_data, 0, sizeof(ConversationData));    conv_data.keepstats = 0;    conv_data.alert_odd_protocols = 0;    /* allow everything by default */    memset(&conv_data.allowed_ip_protocols, 1, 256);        ParseConvArgs(args);    if(mempool_init(&conv_data.state_records,                    conv_data.max_convs, sizeof(StateRecord)))    {        FatalError("ERROR: can't initialize state records\n");    }    conv_data.cachePtr = &conv_data.cache;        ubi_trInitTree(conv_data.cachePtr,/* ptr to the tree head */                   ConvCompareFunc,   /* comparison function */                   0);                /* don't allow overwrites/duplicates */    AddFuncToPreprocList(ConvFunc);    LogMessage("Conversation Config:\n");    LogMessage("   KeepStats: %d\n", conv_data.keepstats);    LogMessage("   Conv Count: %d\n", conv_data.max_convs);    LogMessage("   Timeout   : %d\n", conv_data.timeout);    LogMessage("   Alert Odd?: %d\n", conv_data.alert_odd_protocols);    memset(buf, 0, STD_BUF+1);    snprintf(buf, STD_BUF, "   Allowed IP Protocols: ");        for(i=0;i<256;i++)     {        if(!conv_data.allowed_ip_protocols[i])        {            printall = 0;            break;        }    }    if(printall)    {        sfsnprintfappend(buf, STD_BUF, " All\n");    }    else    {        for(i=0;i<256;i++)         {            if(conv_data.allowed_ip_protocols[i])            {                sfsnprintfappend(buf, STD_BUF, "%d ", i);            }        }    }    LogMessage("%s\n", buf);        conv_data.isInitialized = 1;}/**************************************** *  Called for every packet ****************************************/void ConvFunc(Packet* p, void *context){    StateRecord* srecord;    if(!(p->preprocessors & PP_CONVERSATION))    {        DEBUG_WRAP(DebugMessage(DEBUG_CONVERSATION,                     "Ignoring preprocessor conversation\n"););        return;    }        if (p->packet_flags & PKT_REBUILT_STREAM)     {        DEBUG_WRAP(DebugMessage(DEBUG_CONVERSATION,                     "Ignoring Rebuilt Stream\n"););        return;    }        if (p->iph == NULL)    {        DEBUG_WRAP(DebugMessage(DEBUG_CONVERSATION,                                "ignoring non-ip traffic\n"));        return;    }    /* is this an allowed ip protocol */    if(conv_data.allowed_ip_protocols[p->iph->ip_proto] != 1)    {        if(conv_data.alert_odd_protocols == 1)        {            SnortEventqAdd(GENERATOR_SPP_CONV, CONV_BAD_IP_PROTOCOL,                     1, 0, 5, CONV_BAD_IP_PROTOCOL_STR, 0);        }                return;    }        DEBUG_WRAP(DebugMessage(DEBUG_CONVERSATION,                            "_____________________________\n"                            "%s:%u->",                            inet_ntoa(p->iph->ip_src), p->sp);               DebugMessage(DEBUG_CONVERSATION, "%s:%u\n",                            inet_ntoa(p->iph->ip_dst), p->dp););    /* This will watch portscan watch */    srecord = ConvGetSession(p);    /* Let's try to free up some sessions and then assign out some     *     * If that doesn't work for what ever reason, return out and mark     * the conversation header as NULL indicating that we need to do     * best effort analysis on this packet but we cna't establish it     * as part of an already existing session     *     * would be better to try get, free, alloc, add distinctly to     * avoid an extra lookup     *     */    if(srecord == NULL)    {        DEBUG_WRAP(DebugMessage(DEBUG_CONVERSATION,                                "State table is full! -- %u\n",                                ubi_trCount(conv_data.cachePtr)););                PruneConvCache(p->pkth->ts.tv_sec, 5, NULL);        srecord = ConvGetSession(p);                        if(srecord == NULL)        {            DEBUG_WRAP(DebugMessage(DEBUG_CONVERSATION,                                    "Can't allocate even after a free\n"););            // p->state = NULL;            return;        }    }        srecord->last_time.tv_sec = p->pkth->ts.tv_sec;    srecord->last_time.tv_usec = p->pkth->ts.tv_usec;        if(conv_data.keepstats)    {        FillConvStats(srecord, p);    }        /*     * controls if we will watch for scans on new sessions with     * spp_portscan2     */    if(conv_data.watch_scans && (!(srecord->conv_flags & CONV_MULIPACKETS)))    {        /* only call this if this is the first packet in a conversation */        psWatch(p);    }

⌨️ 快捷键说明

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