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

📄 sf_snort_plugin_api.c

📁 snort2.8.4版本
💻 C
📖 第 1 页 / 共 2 页
字号:
{    return _ded.getRuleData(p);}/*  *  Preprocessor Defined Detection *  *          p: packet data structure, same as the one found in snort. * preprocOpt: data defined in the detection plugin for this rule preprocessor specific option *     cursor: current position within buffer * * Returns:  *    > 0 : match found *    = 0 : no match found * * Predefined constants:  *    (see sf_snort_plugin_api.h for more values) *    RULE_MATCH   -  if preprocessor indicates match *    RULE_NOMATCH -  if preprocessor indicates no match *  */ENGINE_LINKAGE int preprocOptionEval(void *p, PreprocessorOption *preprocOpt, const u_int8_t **cursor){    PreprocOptionEval evalFunc = (PreprocOptionEval)preprocOpt->optionEval;    return evalFunc(p, cursor, preprocOpt->dataPtr);}int isRelativeOption(RuleOption *option){    int thisType = option->optionType;    int relative = 0;    switch (thisType)    {    case OPTION_TYPE_CONTENT:        relative = option->option_u.content->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_PCRE:        relative = option->option_u.pcre->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_FLOWBIT:        /* Never relative */        break;    case OPTION_TYPE_BYTE_TEST:        relative = option->option_u.byte->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_BYTE_JUMP:        relative = option->option_u.byte->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_BYTE_EXTRACT:        relative = option->option_u.byteExtract->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_FLOWFLAGS:        /* Never relative */        break;    case OPTION_TYPE_ASN1:        relative = option->option_u.asn1->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_CURSOR:        relative = option->option_u.cursor->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_LOOP:        /* A Loop is relative, only in that the cursor adjust for         * the loop is always relative.         */        relative = option->option_u.loop->cursorAdjust->flags & CONTENT_RELATIVE;        break;    case OPTION_TYPE_HDR_CHECK:    case OPTION_TYPE_PREPROCESSOR:        /* Never relative */        break;    }    return relative;}/*  *  ruleMatch *  *          p: packet data structure, same as the one found in snort. *    options: NULL terminated list of rule options * * Returns:  *    > 0 : match found *    = 0 : no match found * * Predefined constants:  *    (see sf_snort_plugin_api.h for more values) *    RULE_MATCH   -  if asn1 specifier is found within buffer  *    RULE_NOMATCH -  if asn1 specifier is not found within buffer  *  */int ruleMatchInternal(SFSnortPacket *p, Rule* rule, u_int32_t optIndex, const u_int8_t **cursor){    const u_int8_t *thisCursor = NULL, *startCursor = NULL;    const u_int8_t *tmpCursor = NULL;    int retVal = RULE_NOMATCH;    u_int32_t notFlag = 0;    int thisType;    ContentInfo *thisContentInfo = NULL;    int startAdjust = 0;    u_int32_t origFlags = 0;    int32_t origOffset = 0;    u_int32_t origDepth = 0;    int continueLoop = 1;    PCREInfo *thisPCREInfo = NULL;    if (cursor)        startCursor = thisCursor = *cursor;    if (optIndex >= rule->numOptions || !rule->options[optIndex] )        return RULE_NOMATCH;    thisType = rule->options[optIndex]->optionType;    /* Do some saving off of some info for recursion purposes */    switch (thisType)    {        case OPTION_TYPE_CONTENT:            thisContentInfo = rule->options[optIndex]->option_u.content;            origFlags = thisContentInfo->flags;            origDepth = thisContentInfo->depth;            origOffset = thisContentInfo->offset;            break;        case OPTION_TYPE_PCRE:            thisPCREInfo = rule->options[optIndex]->option_u.pcre;            origFlags = thisPCREInfo->flags;            break;        default:            /* Other checks should not need to check again like             * PCRE & Content do.             */            break;    }    do    {        switch (thisType)        {        case OPTION_TYPE_CONTENT:            retVal = contentMatch(p, rule->options[optIndex]->option_u.content, &thisCursor);            notFlag = rule->options[optIndex]->option_u.content->flags & NOT_FLAG;            break;        case OPTION_TYPE_PCRE:            retVal = pcreMatch(p, rule->options[optIndex]->option_u.pcre, &thisCursor);            notFlag = rule->options[optIndex]->option_u.pcre->flags & NOT_FLAG;            break;        case OPTION_TYPE_FLOWBIT:            retVal = processFlowbits(p, rule->options[optIndex]->option_u.flowBit);            notFlag = rule->options[optIndex]->option_u.flowBit->flags & NOT_FLAG;            break;        case OPTION_TYPE_BYTE_TEST:            retVal = byteTest(p, rule->options[optIndex]->option_u.byte, thisCursor);            notFlag = rule->options[optIndex]->option_u.byte->flags & NOT_FLAG;            break;        case OPTION_TYPE_BYTE_JUMP:            retVal = byteJump(p, rule->options[optIndex]->option_u.byte, &thisCursor);            notFlag = rule->options[optIndex]->option_u.byte->flags & NOT_FLAG;            break;        case OPTION_TYPE_FLOWFLAGS:            retVal = checkFlow(p, rule->options[optIndex]->option_u.flowFlags);            notFlag = rule->options[optIndex]->option_u.flowFlags->flags & NOT_FLAG;            break;        case OPTION_TYPE_ASN1:            retVal = detectAsn1(p, rule->options[optIndex]->option_u.asn1, thisCursor);            notFlag = rule->options[optIndex]->option_u.asn1->flags & NOT_FLAG;            break;        case OPTION_TYPE_CURSOR:            retVal = checkCursor(p, rule->options[optIndex]->option_u.cursor, thisCursor);            notFlag = rule->options[optIndex]->option_u.cursor->flags & NOT_FLAG;            break;        case OPTION_TYPE_SET_CURSOR:            retVal = setCursor(p, rule->options[optIndex]->option_u.cursor, &thisCursor);            notFlag = rule->options[optIndex]->option_u.cursor->flags & NOT_FLAG;            break;        case OPTION_TYPE_HDR_CHECK:            retVal = checkHdrOpt(p, rule->options[optIndex]->option_u.hdrData);            notFlag = rule->options[optIndex]->option_u.hdrData->flags & NOT_FLAG;            break;        case OPTION_TYPE_BYTE_EXTRACT:            retVal = extractValue(p, rule->options[optIndex]->option_u.byteExtract, thisCursor);            notFlag = rule->options[optIndex]->option_u.byteExtract->flags & NOT_FLAG;            break;        case OPTION_TYPE_LOOP:            retVal = loopEval(p, rule->options[optIndex]->option_u.loop, &thisCursor);            notFlag = rule->options[optIndex]->option_u.loop->flags & NOT_FLAG;            break;        case OPTION_TYPE_PREPROCESSOR:            retVal = preprocOptionEval(p, rule->options[optIndex]->option_u.preprocOpt, &thisCursor);            notFlag = rule->options[optIndex]->option_u.preprocOpt->flags & NOT_FLAG;            break;        }        if ( notFlag )        {            if ((retVal <= RULE_NOMATCH))            {                /* Set this as a positive match -- a ! was specified. */                retVal = RULE_MATCH;            }            else  /* Match */            {                retVal = RULE_NOMATCH;            }        }        if (retVal > RULE_NOMATCH)        {            /* This one matched.  Depending on type, check the next one             * either in a loop, or not, saving cursor temporarily.             */            if (optIndex < rule->numOptions -1) /* hehe, optIndex is 0 based */            {                int nestedRetVal;                /* Here's where it gets tricky... */                if (thisType == OPTION_TYPE_CONTENT)                {                    /* If this is a content option, we've found a match.                     * Save off the end-point of the current match.                     * Less the length of current match plus 1.                     *                     * This gives us the starting point to check for this                     * content again if subsequent options fail.  That starting                     * point is the byte AFTER the beginning of the current                     * match.                     */                    if ((origFlags & CONTENT_RELATIVE) && startCursor)                    {                        /* relative content.                         * need to adjust offset/depth as well                         */                        tmpCursor = thisCursor -                            thisContentInfo->patternByteFormLength + thisContentInfo->incrementLength;                        /* Start Adjust is the difference between the old                         * starting point and the 'next' starting point. */                        startAdjust = tmpCursor - startCursor;                    }                    else                    {                        /* non-relative content */                        tmpCursor = thisCursor -                            thisContentInfo->patternByteFormLength + thisContentInfo->incrementLength;                    }                }                else if (thisType == OPTION_TYPE_PCRE)                {                    /* Start next search at end of current pattern */                    /* XXX: Could miss something here if part of pattern                     * repeats but not easy to tell with PCRE.                     */                    tmpCursor = thisCursor;                }                nestedRetVal = ruleMatchInternal(p, rule, optIndex+1, &thisCursor);                if (nestedRetVal == RULE_MATCH)                {                    /* Cool, everyone after us matched, we're done with a match */                    if (cursor)                        *cursor = thisCursor;                    break;                }                /* If Content or PCRE, look farther into the packet                 * for another match. */                if (((thisType == OPTION_TYPE_CONTENT) ||                     (thisType == OPTION_TYPE_PCRE))                     && !notFlag)                {                    /* Only try to find this content again if it is a                     * positive match.                     */                    /* And only if the next option is relative */                    if (!isRelativeOption(rule->options[optIndex+1]))                    {                        /* Match failed, next option is not relative.                          * We're done. */                        retVal = nestedRetVal;                        break;                    }                    switch (thisType)                    {                    case OPTION_TYPE_CONTENT:                        if (origFlags & CONTENT_RELATIVE)                        {                            if ((int32_t)(origDepth - (startAdjust - origOffset)) < (int32_t)thisContentInfo->patternByteFormLength)                            {                                /* Adjusted depth would be less than the content we're searching for?                                 * we're done. */                                retVal = nestedRetVal;                                continueLoop = 0;                            }                            else                            {                                /* For contents that were already relative, adjust the offset & depth fields                                 * from their original values.  Makes it easy to determine when we'll be out                                 * of the original bounds, relative to the original cursor. */                                thisContentInfo->offset = origOffset + startAdjust;                                thisContentInfo->depth = origDepth - startAdjust;                                /* And use the original cursor that was passed in */                                thisCursor = startCursor;                            }                        }                        else                        {                            thisContentInfo->flags |= CONTENT_RELATIVE;                            /* For contents that were not already relative, we simply use the adjusted                             * cursor.  Set thisCursor to tmpCursor as calculated above */                            thisCursor = tmpCursor;                        }                        break;                    case OPTION_TYPE_PCRE:                        /* Doesn't matter if it was already relative,                         * just make it relative anyway.                         */                        thisPCREInfo->flags |= CONTENT_RELATIVE;                        /* For PCREs that were not already relative, we use the cursor                         * that was returned at the end of the pattern to start searching                         * again. */                        thisCursor = tmpCursor;                        break;                    }                    continue;                }                /* Only need to search again when this is a                 * content option.  If its not, we're done. */                if (nestedRetVal <= RULE_NOMATCH)                {                    /* Handle the case when an error is propigated                     * via nestedRetVal.                     */                    retVal = RULE_NOMATCH;                }                break;            }            else            {                /* Cool, nobody after us, we're done with a match */                if (cursor)                    *cursor = thisCursor;                break;            }        }        else        {            /* No match, get outta dodge */            break;        }    } while (continueLoop);    /* Keep looping until we break or serialized content checks returns no match. */    /* Reset the flags for this content in case we added the     * relative flag above.     */    if (thisContentInfo)    {        thisContentInfo->flags = origFlags;        thisContentInfo->offset = origOffset;        thisContentInfo->depth = origDepth;    }    if (thisPCREInfo)    {        thisPCREInfo->flags = origFlags;    }    return retVal;}int ruleMatch(void *p, Rule* rule){    int retVal;    SFSnortPacket *sp = (SFSnortPacket *) p;    /* Uh, stupid rule... Just checking IPs & Ports apparently */    if (rule->numOptions == 0)        return RULE_MATCH;    retVal = ruleMatchInternal(sp, rule, 0, NULL);    /* Special case for rules that just set a flowbit, but     * don't alert.     */    if (rule->noAlert)        return RULE_NOMATCH;    return retVal;}

⌨️ 快捷键说明

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