/**
 * \brief Add a Signature to a SigGroupHead.
 *
 * \param de_ctx Pointer to the detection engine context.
 * \param sgh    Pointer to a SigGroupHead.  Can be NULL also.
 * \param s      Pointer to the Signature that has to be added to the
 *               SigGroupHead.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int SigGroupHeadAppendSig(const DetectEngineCtx *de_ctx, SigGroupHead **sgh,
                          const Signature *s)
{
    if (de_ctx == NULL)
        return 0;

    /* see if we have a head already */
    if (*sgh == NULL) {
        *sgh = SigGroupHeadAlloc(de_ctx, DetectEngineGetMaxSigId(de_ctx) / 8 + 1);
        if (*sgh == NULL)
            goto error;
    }

    /* enable the sig in the bitarray */
    (*sgh)->init->sig_array[s->num / 8] |= 1 << (s->num % 8);

    return 0;

error:
    return -1;
}
/**
 * \brief Check if a SigGroupHead contains a Signature, whose sid is sent as an
 *        argument.
 *
 * \param de_ctx Pointer to the detection engine context.
 * \param sgh    Pointer to the SigGroupHead that has to be checked for the
 *               presence of a Signature.
 * \param sid    The Signature id(sid) that has to be checked in the SigGroupHead.
 *
 * \retval 1 On successfully finding the sid in the SigGroupHead.
 * \retval 0 If the sid is not found in the SigGroupHead
 */
int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
                              uint32_t sid)
{
    SCEnter();

    uint32_t sig = 0;
    Signature *s = NULL;
    uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx);

    if (sgh == NULL) {
        SCReturnInt(0);
    }

    for (sig = 0; sig < max_sid; sig++) {
        if (sgh->init->sig_array == NULL) {
            SCReturnInt(0);
        }

        /* Check if the SigGroupHead has an entry for the sid */
        if ( !(sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) )
            continue;

        /* If we have reached here, we have an entry for sid in the SigGrouHead.
         * Retrieve the Signature from the detection engine context */
        s = de_ctx->sig_array[sig];
        if (s == NULL)
            continue;

        /* If the retrieved Signature matches the sid arg, we have a match */
        if (s->id == sid) {
            SCReturnInt(1);
        }
    }

    SCReturnInt(0);
}
Exemple #3
0
/** \brief Get MpmStore for a built-in buffer type
 *
 */
MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
                                enum MpmBuiltinBuffers buf)
{
    const Signature *s = NULL;
    uint32_t sig;
    uint32_t cnt = 0;
    int direction = 0;
    uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx) / 8 + 1;
    uint8_t sids_array[max_sid];
    memset(sids_array, 0x00, max_sid);
    int sgh_mpm_context = 0;

    switch (buf) {
        case MPMB_TCP_PKT_TS:
        case MPMB_TCP_PKT_TC:
            sgh_mpm_context = de_ctx->sgh_mpm_context_proto_tcp_packet;
            break;
        case MPMB_TCP_STREAM_TS:
        case MPMB_TCP_STREAM_TC:
            sgh_mpm_context = de_ctx->sgh_mpm_context_stream;
            break;
        case MPMB_UDP_TS:
        case MPMB_UDP_TC:
            sgh_mpm_context = de_ctx->sgh_mpm_context_proto_udp_packet;
            break;
        case MPMB_OTHERIP:
            sgh_mpm_context = de_ctx->sgh_mpm_context_proto_other_packet;
            break;
        default:
            break;
    }

    switch(buf) {
        case MPMB_TCP_PKT_TS:
        case MPMB_TCP_STREAM_TS:
        case MPMB_UDP_TS:
            direction = SIG_FLAG_TOSERVER;
            break;

        case MPMB_TCP_PKT_TC:
        case MPMB_TCP_STREAM_TC:
        case MPMB_UDP_TC:
            direction = SIG_FLAG_TOCLIENT;
            break;

        case MPMB_OTHERIP:
            direction = (SIG_FLAG_TOCLIENT|SIG_FLAG_TOSERVER);
            break;

        case MPMB_MAX:
            BUG_ON(1);
            break;
    }

    for (sig = 0; sig < sgh->sig_cnt; sig++) {
        s = sgh->match_array[sig];
        if (s == NULL)
            continue;

        if (s->mpm_sm == NULL)
            continue;

        int list = SigMatchListSMBelongsTo(s, s->mpm_sm);
        if (list < 0)
            continue;

        if (list != DETECT_SM_LIST_PMATCH)
            continue;

        switch (buf) {
            case MPMB_TCP_PKT_TS:
            case MPMB_TCP_PKT_TC:
                if (SignatureHasPacketContent(s) == 1)
                {
                    sids_array[s->num / 8] |= 1 << (s->num % 8);
                    cnt++;
                }
                break;
            case MPMB_TCP_STREAM_TS:
            case MPMB_TCP_STREAM_TC:
                if (SignatureHasStreamContent(s) == 1)
                {
                    sids_array[s->num / 8] |= 1 << (s->num % 8);
                    cnt++;
                }
                break;
            case MPMB_UDP_TS:
            case MPMB_UDP_TC:
                sids_array[s->num / 8] |= 1 << (s->num % 8);
                cnt++;
                break;
            case MPMB_OTHERIP:
                sids_array[s->num / 8] |= 1 << (s->num % 8);
                cnt++;
                break;
            default:
                break;
        }
    }

    if (cnt == 0)
        return NULL;

    MpmStore lookup = { sids_array, max_sid, direction, buf, DETECT_SM_LIST_PMATCH, 0, NULL};

    MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
    if (result == NULL) {
        MpmStore *copy = SCCalloc(1, sizeof(MpmStore));
        if (copy == NULL)
            return NULL;
        uint8_t *sids = SCCalloc(1, max_sid);
        if (sids == NULL) {
            SCFree(copy);
            return NULL;
        }

        memcpy(sids, sids_array, max_sid);
        copy->sid_array = sids;
        copy->sid_array_size = max_sid;
        copy->buffer = buf;
        copy->direction = direction;
        copy->sm_list = DETECT_SM_LIST_PMATCH;
        copy->sgh_mpm_context = sgh_mpm_context;

        MpmStoreSetup(de_ctx, copy);
        MpmStoreAdd(de_ctx, copy);
        return copy;
    } else {
        return result;
    }
}
Exemple #4
0
MpmStore *MpmStorePrepareBuffer2(DetectEngineCtx *de_ctx, SigGroupHead *sgh, AppLayerMpms *am)
{
    const Signature *s = NULL;
    uint32_t sig;
    uint32_t cnt = 0;
    uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx) / 8 + 1;
    uint8_t sids_array[max_sid];
    memset(sids_array, 0x00, max_sid);

    SCLogDebug("handling %s direction %s for list %d", am->name,
            am->direction == SIG_FLAG_TOSERVER ? "toserver" : "toclient", am->sm_list);

    for (sig = 0; sig < sgh->sig_cnt; sig++) {
        s = sgh->match_array[sig];
        if (s == NULL)
            continue;

        if (s->mpm_sm == NULL)
            continue;

        int list = SigMatchListSMBelongsTo(s, s->mpm_sm);
        if (list < 0)
            continue;

        if ((s->flags & am->direction) == 0)
            continue;

        if (list != am->sm_list)
            continue;

        sids_array[s->num / 8] |= 1 << (s->num % 8);
        cnt++;
    }

    if (cnt == 0)
        return NULL;

    MpmStore lookup = { sids_array, max_sid, am->direction, MPMB_MAX, am->sm_list, 0, NULL};

    MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
    if (result == NULL) {
        SCLogDebug("new unique mpm for %s %s: %u patterns",
                am->name, am->direction == SIG_FLAG_TOSERVER ? "toserver" : "toclient", cnt);

        MpmStore *copy = SCCalloc(1, sizeof(MpmStore));
        if (copy == NULL)
            return NULL;
        uint8_t *sids = SCCalloc(1, max_sid);
        if (sids == NULL) {
            SCFree(copy);
            return NULL;
        }

        memcpy(sids, sids_array, max_sid);
        copy->sid_array = sids;
        copy->sid_array_size = max_sid;
        copy->buffer = MPMB_MAX;
        copy->direction = am->direction;
        copy->sm_list = am->sm_list;
        copy->sgh_mpm_context = am->sgh_mpm_context;

        MpmStoreSetup(de_ctx, copy);
        MpmStoreAdd(de_ctx, copy);
        return copy;
    } else {
        return result;
    }
    return NULL;
}