/** * \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); }
/** \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; } }
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; }