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

📄 sp_dynamic.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
字号:
/* $Id$ *//* * sp_dynamic.c * * 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. * * Copyright (C) 2005 Sourcefire Inc. * * Author: Steven Sturges * * Purpose: *      Supports dynamically loaded detection plugin to check the packet. * *      does not update the doe_ptr * * Arguments: *      Required: *        None *      Optional: *        None * *   sample rules: *   alert tcp any any -> any any (msg: "DynamicRuleCheck"; ); * * Effect: * *      Returns 1 if the dynamic detection plugin matches, 0 if it doesn't. * * Comments: * * */#ifdef DYNAMIC_PLUGIN#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>#include <stdlib.h>#include <ctype.h>#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <errno.h>#include "rules.h"#include "decode.h"#include "bitop_funcs.h"#include "plugbase.h"#include "parser.h"#include "debug.h"#include "util.h"#include "plugin_enum.h"#include "sp_dynamic.h"#include "sf_dynamic_engine.h"#include "detection-plugins/sp_flowbits.h"#include "detection-plugins/sp_asn1_detect.h"void DynamicInit(char *, OptTreeNode *, int);void DynamicParse(char *, OptTreeNode *);int DynamicCheck(Packet *, struct _OptTreeNode *, OptFpList *);/**************************************************************************** *  * Function: SetupDynamic() * * Purpose: Load it up * * Arguments: None. * * Returns: void function * ****************************************************************************/void SetupDynamic(void){    /* map the keyword to an initialization/processing function */    RegisterPlugin("dynamic", DynamicInit, OPT_TYPE_DETECTION);    DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Plugin: Dynamic Setup\n"););}/**************************************************************************** *  * Function: DynamicInit(char *, OptTreeNode *) * * Purpose: Configuration function.  Handles parsing the rule  *          information and attaching the associated detection function to *          the OTN. * * Arguments: data => rule arguments/data *            otn => pointer to the current rule option list node *            protocol => protocol the rule is on (we don't care in this case) * * Returns: void function * ****************************************************************************/void DynamicInit(char *data, OptTreeNode *otn, int protocol){    OptFpList *fpl;    DynamicData *dynData;    dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC];    fpl = AddOptFuncToList(DynamicCheck, otn);    /* attach it to the context node so that we can call each instance     * individually     */    fpl->context = (void *) NULL;}/**************************************************************************** *  * Function: DynamicCheck(char *, OptTreeNode *, OptFpList *) * * Purpose: Use this function to perform the particular detection routine *          that this rule keyword is supposed to encompass. * * Arguments: p => pointer to the decoded packet *            otn => pointer to the current rule's OTN *            fp_list => pointer to the function pointer list * * Returns: If the detection test fails, this function *must* return a zero! *          On success, it calls the next function in the detection list  * ****************************************************************************/int DynamicCheck(Packet *p, struct _OptTreeNode *otn, OptFpList *fp_list){    DynamicData *dynData;    int result = 0;        dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC];    if (!dynData)    {        LogMessage("Dynamic Rule with no context data available");        return 0;    }    result = dynData->checkFunction((void *)p, dynData->contextData);    if (result)    {        return fp_list->next->OptTestFunc(p, otn, fp_list->next);    }    /* Detection failed */    return 0;}/**************************************************************************** *  * Function: RegisterDynamicRule(u_int32_t, u_int32_t, char *, void *, *                               OTNCheckFunction, int, GetFPContentFunction) * * Purpose: A dynamically loaded detection engine library can use this *          function to register a dynamically loaded rule/preprocessor.  It *          provides a pointer to context specific data for the *          rule/preprocessor and a reference to the function used to *          check the rule. * * Arguments: sid => Signature ID *            gid => Generator ID   *            info => context specific data *            chkFunc => Function to call to check if the rule matches *            fpContentFlags => Flags indicating which Fast Pattern Contents *                              are available *            fpFunc => Function to call to get list of fast pattern contents * * Returns: 0 on success * ****************************************************************************/int RegisterDynamicRule(u_int32_t sid, u_int32_t gid, void *info, OTNCheckFunction chkFunc,                         OTNHasFunction hasFlowFunc,                        OTNHasFunction hasFlowbitFunc,                        OTNHasFunction hasContentFunc,                        OTNHasFunction hasByteTestFunc,                        OTNHasFunction hasPCREFunc,                        int fpContentFlags, GetFPContentFunction fpFunc){    DynamicData *dynData;    struct _OptTreeNode *otn = NULL;    OptFpList *idx;     /* index pointer */    OptFpList *prev = NULL;    OptFpList *fpl;    /* Get OTN/RTN from SID */    otn = soid_sg_otn_lookup(gid, sid);    if (!otn)    {#ifndef SOURCEFIRE         LogMessage("DynamicPlugin: Rule [%u:%u] not enabled in configuration, rule will not be used.\n", gid, sid);#endif        //LogMessage("DynamicPlugin: Unable to find record of Rule Node for %d:%d\n", sid, gid);        return -1;    }    /* allocate the data structure and attach it to the     * rule's data struct list */    dynData = (DynamicData *) SnortAlloc(sizeof(DynamicData));    if(dynData == NULL)    {        FatalError("DynamicPlugin: Unable to allocate Dynamic data node for rule [%u:%u]\n",                    gid, sid);    }    dynData->contextData = info;    dynData->checkFunction = chkFunc;    dynData->hasFlowFunction = hasFlowFunc;    dynData->hasFlowbitFunction = hasFlowbitFunc;    dynData->hasContentFunction = hasContentFunc;    dynData->hasByteTestFunction = hasByteTestFunc;    dynData->hasPCREFunction = hasPCREFunc;    dynData->fastPatternContents = fpFunc;    dynData->fpContentFlags = fpContentFlags;    while (otn)    {        otn->ds_list[PLUGIN_DYNAMIC] = (void *)dynData;        /* And add this function into the tail of the list */        fpl = AddOptFuncToList(DynamicCheck, otn);        fpl->context = NULL;        /* Arrgh.  Because we read this rule in earlier, there is         * already an OptListEnd node there.  Need to mvoe this new         * one to just before it.         */        DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n"););        /* set the index pointer to the start of this OTN's function list */        idx = otn->opt_func;        /* if there are no nodes on the function list... */        while(idx != NULL)        {            if (idx->next == fpl) /* The last one in the list before us */            {                if (prev)                {                    prev->next = fpl;                    fpl->next = idx;                    idx->next = NULL;                }                else /* idx is the head of the list */                {                    otn->opt_func = fpl;                    fpl->next = idx;                    idx->next = NULL;                }            }            prev = idx;            idx = idx->next;        }        otn = soid_sg_otn_lookup_next(gid, sid);    }    return 0;}extern SFGHASH *flowbits_hash;extern u_int32_t flowbits_count;u_int32_t DynamicFlowbitRegister(char *name, int op){    u_int32_t retFlowId; /* ID */    int hashRet;    FLOWBITS_OBJECT *flowbits_item = sfghash_find(flowbits_hash, name);    if (flowbits_item)    {        flowbits_item->types |= op;        retFlowId = flowbits_item->id;    }    else    {        flowbits_item = (FLOWBITS_OBJECT *)SnortAlloc(sizeof(FLOWBITS_OBJECT));        flowbits_item->id = flowbits_count;        flowbits_item->types |= op;        hashRet = sfghash_add(flowbits_hash, name, flowbits_item);        if (hashRet)        {            FatalError("DynamicPlugin: Unable to add flowbits key (%s) to hash", name);        }                    retFlowId = flowbits_item->id;        flowbits_count++;        if(flowbits_count >= (giFlowbitSize<<3) )        {            FatalError("FLOWBITS ERROR: The number of flowbit IDs in the "                       "current ruleset (%d) exceed the maximum number of IDs "                       "that are allowed (%d).\n", flowbits_count,giFlowbitSize<<3);        }    }    return retFlowId;}int DynamicFlowbitCheck(void *pkt, int op, u_int32_t id){    StreamFlowData *flowdata;    Packet *p = (Packet *)pkt;    int result = 0;    flowdata = GetFlowbitsData(p);    if (!flowdata)    {        return 0;    }    switch(op)    {        case FLOWBITS_SET:            boSetBit(&(flowdata->boFlowbits), id);            result = 1;            break;        case FLOWBITS_UNSET:            boClearBit(&(flowdata->boFlowbits), id);            result = 1;            break;        case FLOWBITS_RESET:            boResetBITOP(&(flowdata->boFlowbits));            result = 1;        case FLOWBITS_ISSET:            if (boIsBitSet(&(flowdata->boFlowbits), id))                result = 1;            break;        case FLOWBITS_ISNOTSET:            if (boIsBitSet(&(flowdata->boFlowbits), id))                result = 0;            else                result = 1;            break;        case FLOWBITS_TOGGLE:            if (boIsBitSet(&(flowdata->boFlowbits), id))            {                boClearBit(&(flowdata->boFlowbits), id);            }            else            {                boSetBit(&(flowdata->boFlowbits), id);            }            result = 1;            break;        case FLOWBITS_NOALERT:            /* Shouldn't see this case here... But, just for             * safety sake, return 0.             */            result = 0;            break;        default:            /* Shouldn't see this case here... But, just for             * safety sake, return 0.             */            result = 0;            break;    }    return result;}int DynamicAsn1Detect(void *pkt, void *ctxt, const u_int8_t *cursor){    Packet *p    = (Packet *) pkt;    ASN1_CTXT *c = (ASN1_CTXT *) ctxt;           /* Call same detection function that snort calls */    return Asn1DoDetect(p->data, p->dsize, c, cursor);}int DynamicHasFlow(OptTreeNode *otn){    DynamicData *dynData;        dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC];    if (!dynData)    {        return 0;    }    return dynData->hasFlowFunction(dynData->contextData);}int DynamicHasFlowbit(OptTreeNode *otn){    DynamicData *dynData;        dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC];    if (!dynData)    {        return 0;    }    return dynData->hasFlowbitFunction(dynData->contextData);}int DynamicHasContent(OptTreeNode *otn){    DynamicData *dynData;        dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC];    if (!dynData)    {        return 0;    }    return dynData->hasContentFunction(dynData->contextData);}int DynamicHasByteTest(OptTreeNode *otn){    DynamicData *dynData;        dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC];    if (!dynData)    {        return 0;    }    return dynData->hasByteTestFunction(dynData->contextData);}int DynamicHasPCRE(OptTreeNode *otn){    DynamicData *dynData;        dynData = (DynamicData *)otn->ds_list[PLUGIN_DYNAMIC];    if (!dynData)    {        return 0;    }    return dynData->hasPCREFunction(dynData->contextData);}#endif /* DYNAMIC_PLUGIN */

⌨️ 快捷键说明

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