*/
void IPOnlyInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
{
- io_ctx->tree_ipv4src = SCRadixCreateRadixTree(SigNumArrayFree,
- SigNumArrayPrint);
- io_ctx->tree_ipv4dst = SCRadixCreateRadixTree(SigNumArrayFree,
- SigNumArrayPrint);
- io_ctx->tree_ipv6src = SCRadixCreateRadixTree(SigNumArrayFree,
- SigNumArrayPrint);
- io_ctx->tree_ipv6dst = SCRadixCreateRadixTree(SigNumArrayFree,
- SigNumArrayPrint);
+ io_ctx->tree_ipv4src = SCRadixCreateRadixTree(SigNumArrayFree, SigNumArrayPrint);
+ io_ctx->tree_ipv4dst = SCRadixCreateRadixTree(SigNumArrayFree, SigNumArrayPrint);
+ io_ctx->tree_ipv6src = SCRadixCreateRadixTree(SigNumArrayFree, SigNumArrayPrint);
+ io_ctx->tree_ipv6dst = SCRadixCreateRadixTree(SigNumArrayFree, SigNumArrayPrint);
+
+ io_ctx->sig_mapping = SCCalloc(1, de_ctx->sig_array_len * sizeof(uint32_t));
+ if (io_ctx->sig_mapping == NULL) {
+ FatalError(SC_ERR_MEM_ALLOC, "Unable to allocate iponly signature tracking area");
+ }
+ io_ctx->sig_mapping_size = 0;
+}
+
+SigIntId IPOnlyTrackSigNum(DetectEngineIPOnlyCtx *io_ctx, SigIntId signum)
+{
+ SigIntId loc = io_ctx->sig_mapping_size;
+ io_ctx->sig_mapping[loc] = signum;
+ io_ctx->sig_mapping_size++;
+ return loc;
}
/**
if (io_ctx->tree_ipv6dst != NULL)
SCRadixReleaseRadixTree(io_ctx->tree_ipv6dst);
io_ctx->tree_ipv6dst = NULL;
+
+ if (io_ctx->sig_mapping != NULL)
+ SCFree(io_ctx->sig_mapping);
+ io_ctx->sig_mapping = NULL;
}
/**
for (u = 0; u < src->size; u++) {
SCLogDebug("And %"PRIu8" & %"PRIu8, src->array[u], dst->array[u]);
- /* The final results will be at io_tctx */
- io_tctx->sig_match_array[u] = dst->array[u] & src->array[u];
+ uint8_t bitarray = dst->array[u] & src->array[u];
/* We have to move the logic of the signature checking
* to the main detect loop, in order to apply the
* priority of actions (pass, drop, reject, alert) */
- if (io_tctx->sig_match_array[u] != 0) {
+ if (bitarray) {
/* We have a match :) Let's see from which signum's */
- uint8_t bitarray = io_tctx->sig_match_array[u];
uint8_t i = 0;
for (; i < 8; i++, bitarray = bitarray >> 1) {
if (bitarray & 0x01) {
- Signature *s = de_ctx->sig_array[u * 8 + i];
+ Signature *s = de_ctx->sig_array[io_ctx->sig_mapping[u * 8 + i]];
if ((s->proto.flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) {
SCLogDebug("ip version didn't match");
if (!(s->flags & SIG_FLAG_IPONLY))
return;
+ SigIntId mapped_signum = IPOnlyTrackSigNum(io_ctx, s->num);
+ SCLogDebug("Adding IPs from rule: %" PRIu32 " (%s) as %" PRIu32 " mapped to %" PRIu32 "\n",
+ s->id, s->msg, s->num, mapped_signum);
/* Set the internal signum to the list before merging */
- IPOnlyCIDRListSetSigNum(s->CidrSrc, s->num);
+ IPOnlyCIDRListSetSigNum(s->CidrSrc, mapped_signum);
- IPOnlyCIDRListSetSigNum(s->CidrDst, s->num);
+ IPOnlyCIDRListSetSigNum(s->CidrDst, mapped_signum);
/**
* ipv4 and ipv6 are mixed, but later we will separate them into
io_ctx->ip_src = IPOnlyCIDRItemInsert(io_ctx->ip_src, s->CidrSrc);
io_ctx->ip_dst = IPOnlyCIDRItemInsert(io_ctx->ip_dst, s->CidrDst);
- if (s->num > io_ctx->max_idx)
- io_ctx->max_idx = s->num;
+ if (mapped_signum > io_ctx->max_idx)
+ io_ctx->max_idx = mapped_signum;
/** no longer ref to this, it's in the table now */
s->CidrSrc = NULL;