diff --git a/src/decode.c b/src/decode.c index b9a071cd77..4d696c845f 100644 --- a/src/decode.c +++ b/src/decode.c @@ -115,3 +115,26 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) return; } + +/** + * \brief Debug print function for printing addresses + * + * \param Address object + * + * \todo IPv6 + */ +void AddressDebugPrint(Address *a) { + if (a == NULL) + return; + + switch (a->family) { + case AF_INET: + { + char s[16]; + inet_ntop(AF_INET, (const void *)&a->addr_data32[0], s, sizeof(s)); + SCLogDebug("%s", s); + break; + } + } +} + diff --git a/src/decode.h b/src/decode.h index fe6bc016db..5e7d32a1f6 100644 --- a/src/decode.h +++ b/src/decode.h @@ -483,6 +483,8 @@ void DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, Packet *SetupPkt (void); Packet *TunnelPktSetup(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, uint8_t); +void AddressDebugPrint(Address *); + /** \brief Set the No payload inspection Flag for the packet. * * \param p Packet to set the flag in diff --git a/src/detect-engine-address.c b/src/detect-engine-address.c index 84697ee946..2b8e088a90 100644 --- a/src/detect-engine-address.c +++ b/src/detect-engine-address.c @@ -1435,27 +1435,35 @@ int DetectAddressCmp(DetectAddress *a, DetectAddress *b) */ int DetectAddressMatch(DetectAddress *dd, Address *a) { - if (dd->family != a->family) - return 0; + SCEnter(); + + if (dd->family != a->family) { + SCReturnInt(0); + } + + //DetectAddressPrint(dd); + //AddressDebugPrint(a); switch (a->family) { case AF_INET: + /* XXX figure out a way to not need to do this ntohl if we switch to * Address inside DetectAddressData we can do uint8_t checks */ if (ntohl(a->addr_data32[0]) >= ntohl(dd->ip[0]) && - ntohl(a->addr_data32[0]) <= ntohl(dd->ip2[0])) { - return 1; + ntohl(a->addr_data32[0]) <= ntohl(dd->ip2[0])) + { + SCReturnInt(1); } else { - return 0; + SCReturnInt(0); } break; case AF_INET6: if (AddressIPv6Ge(a->addr_data32, dd->ip) == 1 && - AddressIPv6Le(a->addr_data32, dd->ip2) == 1) { - return 1; + AddressIPv6Le(a->addr_data32, dd->ip2) == 1) { + SCReturnInt(1); } else { - return 0; + SCReturnInt(0); } break; @@ -1464,7 +1472,7 @@ int DetectAddressMatch(DetectAddress *dd, Address *a) break; } - return 0; + SCReturnInt(0); } /** @@ -1520,25 +1528,33 @@ void DetectAddressPrint(DetectAddress *gr) */ DetectAddress *DetectAddressLookupInHead(DetectAddressHead *gh, Address *a) { + SCEnter(); + DetectAddress *g; - if (gh == NULL) - return NULL; + if (gh == NULL) { + SCReturnPtr(NULL, "DetectAddress"); + } /* XXX should we really do this check every time we run this function? */ - if (a->family == AF_INET) + if (a->family == AF_INET) { + SCLogDebug("IPv4"); g = gh->ipv4_head; - else if (a->family == AF_INET6) + } else if (a->family == AF_INET6) { + SCLogDebug("IPv6"); g = gh->ipv6_head; - else + } else { + SCLogDebug("ANY"); g = gh->any_head; + } for ( ; g != NULL; g = g->next) { - if (DetectAddressMatch(g,a) == 1) - return g; + if (DetectAddressMatch(g,a) == 1) { + SCReturnPtr(g, "DetectAddress"); + } } - return NULL; + SCReturnPtr(NULL, "DetectAddress"); } /********************************Unittests*************************************/ diff --git a/src/detect-engine-port.c b/src/detect-engine-port.c index 06952957b8..99da43d848 100644 --- a/src/detect-engine-port.c +++ b/src/detect-engine-port.c @@ -830,10 +830,10 @@ void DetectPortPrint(DetectPort *dp) { if (dp->flags & PORT_FLAG_ANY) { SCLogDebug("=> port %p: ANY", dp); - //printf("ANY"); +// printf("ANY"); } else { SCLogDebug("=> port %p %" PRIu32 "-%" PRIu32 "", dp, dp->port, dp->port2); - //printf("%" PRIu32 "-%" PRIu32 "", dp->port, dp->port2); +// printf("%" PRIu32 "-%" PRIu32 "", dp->port, dp->port2); } } diff --git a/src/detect-engine-siggroup.c b/src/detect-engine-siggroup.c index db4a68902a..e81f1b2002 100644 --- a/src/detect-engine-siggroup.c +++ b/src/detect-engine-siggroup.c @@ -1060,12 +1060,18 @@ void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { SCEnter(); - uint32_t i; + if (sgh == NULL) { + SCReturn; + } + + uint32_t u; SCLogDebug("The Signatures present in this SigGroupHead are: "); - for (i = 0; i < sgh->sig_size; i++) { - if (sgh->sig_array[i / 8] & (1 << (i % 8))) - SCLogDebug("%" PRIu32, i); + for (u = 0; u < (sgh->sig_size * 8); u++) { + if (sgh->sig_array[u / 8] & (1 << (u % 8))) { + SCLogDebug("%" PRIu32, u); + printf("s->num %"PRIu16" ", u); + } } SCReturn; @@ -1850,6 +1856,56 @@ static int SigGroupHeadTest09(void) return result; } +/** + * \test ICMP(?) sig grouping bug. + */ +static int SigGroupHeadTest10(void) +{ + int result = 0; + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + Signature *s = NULL; + Packet p; + DetectEngineThreadCtx *det_ctx = NULL; + ThreadVars th_v; + + memset(&th_v, 0, sizeof(ThreadVars)); + memset(&p, 0, sizeof(Packet)); + p.proto = IPPROTO_ICMP; + p.type = 5; + p.code = 1; + p.src.family = AF_INET; + p.dst.family = AF_INET; + p.src.addr_data32[0] = 0xe08102d3; + p.dst.addr_data32[0] = 0x3001a8c0; + + if (de_ctx == NULL) + return 0; + + s = DetectEngineAppendSig(de_ctx, "alert icmp 192.168.0.0/16 any -> any any (icode:>1; itype:11; sid:1; rev:1;)"); + if (s == NULL) { + goto end; + } + s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> 192.168.0.0/16 any (icode:1; itype:5; sid:2; rev:1;)"); + if (s == NULL) { + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + AddressDebugPrint(&p.dst); + + SigGroupHead *sgh = SigMatchSignaturesGetSgh(&th_v, de_ctx, det_ctx, &p); + if (sgh == NULL) { + goto end; + } + + result = 1; +end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} #endif void SigGroupHeadRegisterTests(void) @@ -1866,6 +1922,7 @@ void SigGroupHeadRegisterTests(void) UtRegisterTest("SigGroupHeadTest07", SigGroupHeadTest07, 1); UtRegisterTest("SigGroupHeadTest08", SigGroupHeadTest08, 1); UtRegisterTest("SigGroupHeadTest09", SigGroupHeadTest09, 1); + UtRegisterTest("SigGroupHeadTest10", SigGroupHeadTest10, 1); #endif diff --git a/src/detect-engine-siggroup.h b/src/detect-engine-siggroup.h index 5afeda9138..c6e361acee 100644 --- a/src/detect-engine-siggroup.h +++ b/src/detect-engine-siggroup.h @@ -76,5 +76,6 @@ int SigGroupHeadContainsSigId (DetectEngineCtx *de_ctx, SigGroupHead *sgh, uint32_t sid); void SigGroupHeadRegisterTests(void); +void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh); #endif /* __DETECT_ENGINE_SIGGROUP_H__ */ diff --git a/src/detect.c b/src/detect.c index 719ee7e1d6..cd5256a72e 100644 --- a/src/detect.c +++ b/src/detect.c @@ -202,6 +202,28 @@ void DetectExitPrintStats(ThreadVars *tv, void *data) { SCLogInfo("%"PRIu64" sigs per mpm match on avg needed inspection, total mpm searches %"PRIu64", less than 25 sigs need inspect %"PRIu64", more than 100 sigs need inspect %"PRIu64", more than 1000 %"PRIu64" max %"PRIu64"", det_ctx->mpm_match ? det_ctx->mpm_sigs / det_ctx->mpm_match : 0, det_ctx->mpm_match, det_ctx->mpm_sigsmin25, det_ctx->mpm_sigsplus100, det_ctx->mpm_sigsplus1000, det_ctx->mpm_sigsmax); } +int SghHasSig(DetectEngineCtx *de_ctx, SigGroupHead *sgh, uint32_t sid) { + if (sgh == NULL) { + return 0; + } + + uint32_t sig; + for (sig = 0; sig < DetectEngineGetMaxSigId(de_ctx); sig++) { + if (!(sgh->sig_array[(sig/8)] & (1<<(sig%8)))) + continue; + + Signature *s = de_ctx->sig_array[sig]; + if (s == NULL) + continue; + + if (sid == s->id) { + return 1; + } + } + + return 0; +} + /** \brief Create the path if default-rule-path was specified * \param sig_file The name of the file * \retval str Pointer to the string path + sig_file @@ -1135,6 +1157,7 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) { } cnt++; } + for (gr = tmp_s->src.ipv6_head; gr != NULL; gr = gr->next) { if (SigGroupHeadAppendSig(de_ctx, &gr->sh, tmp_s) < 0) { goto error; @@ -1147,6 +1170,7 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) { } cnt++; } + de_ctx->sig_cnt++; } @@ -1314,6 +1338,8 @@ static int DetectEngineLookupFlowAddSig(DetectEngineCtx *de_ctx, DetectEngineLoo * */ static int DetectEngineLookupDsizeAddSig(DetectEngineCtx *de_ctx, Signature *s, int family) { + SCEnter(); + uint16_t low = 0, high = 65535; if (s->flags & SIG_FLAG_DSIZE) { @@ -1365,7 +1391,7 @@ static int DetectEngineLookupDsizeAddSig(DetectEngineCtx *de_ctx, Signature *s, g_detectengine_any_big++; } - return 0; + SCReturnInt(0); } static DetectAddress *GetHeadPtr(DetectAddressHead *head, int family) { @@ -1783,6 +1809,7 @@ int SigAddressPrepareStage2(DetectEngineCtx *de_ctx) { de_ctx->dsize_gh[ds].flow_gh[f].tmp_gh[proto]->ipv4_head, AF_INET, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto], groups, CreateGroupedAddrListCmpMpmMaxlen, DetectEngineGetMaxSigId(de_ctx)); + CreateGroupedAddrList(de_ctx, de_ctx->dsize_gh[ds].flow_gh[f].tmp_gh[proto]->ipv6_head, AF_INET6, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto], groups, @@ -1915,6 +1942,9 @@ error: return -1; } +/** + * \brief Build the destination address portion of the match tree + */ int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *head, int family, int dsize, int flow) { Signature *tmp_s = NULL; DetectAddress *gr = NULL, *sgr = NULL, *lookup_gr = NULL; @@ -1927,7 +1957,7 @@ int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *hea /* loop through the global source address list */ for (gr = grhead; gr != NULL; gr = gr->next) { - //printf(" * Source group: "); DetectAddressPrint(gr); printf("\n"); + //printf(" * Source group (BuildDestinationAddressHeads): "); DetectAddressPrint(gr); printf(" (%p)\n", gr); /* initialize the destination group head */ gr->dst_gh = DetectAddressHeadInit(); @@ -1946,17 +1976,20 @@ int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *hea continue; tmp_s = de_ctx->sig_array[sig]; - if (tmp_s == NULL) continue; + //printf(" * (tmp) Signature %u (num %u)\n", tmp_s->id, tmp_s->num); + max_idx = sig; /* build the temp list */ grsighead = GetHeadPtr(&tmp_s->dst, family); for (sgr = grsighead; sgr != NULL; sgr = sgr->next) { + //printf(" * (tmp) dst group: "); DetectAddressPrint(sgr); printf(" (%p)\n", sgr); + if ((lookup_gr = DetectAddressLookupInList(tmp_gr_list, sgr)) == NULL) { - DetectAddress *grtmp = DetectAddressCopy(gr); + DetectAddress *grtmp = DetectAddressCopy(sgr); if (grtmp == NULL) { goto error; } @@ -1984,7 +2017,7 @@ int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *hea */ grdsthead = GetHeadPtr(gr->dst_gh, family); for (sgr = grdsthead; sgr != NULL; sgr = sgr->next) { - //printf(" * Destination group: "); DetectAddressPrint(sgr); printf("\n"); + //printf(" * Destination group: "); DetectAddressPrint(sgr); printf("\n"); /* Because a pattern matcher context uses quite some * memory, we first check if we can reuse it from @@ -2086,7 +2119,8 @@ error: return -1; } -static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, DetectAddressHead *head, int family, int dsize, int flow) { +//static +int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, DetectAddressHead *head, int family, int dsize, int flow) { Signature *tmp_s = NULL; DetectAddress *src_gr = NULL, *dst_gr = NULL, *sig_gr = NULL, *lookup_gr = NULL; DetectAddress *src_gr_head = NULL, *dst_gr_head = NULL, *sig_gr_head = NULL; @@ -2442,7 +2476,6 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) { printf ("BuildDestinationAddressHeads(src_gh[6],AF_INET) failed\n"); goto error; } -//#if 0 r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[17],AF_INET,ds,f); if (r < 0) { printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n"); @@ -2468,7 +2501,6 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) { printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n"); goto error; } - for (proto = 0; proto < 256; proto++) { if (proto == IPPROTO_TCP || proto == IPPROTO_UDP) continue; @@ -2491,7 +2523,6 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) { } } } -//#endif /* cleanup group head (uri)content_array's */ SigGroupHeadFreeMpmArrays(de_ctx); @@ -2622,17 +2653,31 @@ int SigAddressPrepareStage5(DetectEngineCtx *de_ctx) { int ds, f, proto; for (ds = 0; ds < DSIZE_STATES; ds++) { + printf("\n"); for (f = 0; f < FLOW_STATES; f++) { + printf("\n"); for (proto = 0; proto < 256; proto++) { - if (proto != 17) + if (proto != 1) continue; for (global_src_gr = de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto]->ipv4_head; global_src_gr != NULL; global_src_gr = global_src_gr->next) { printf("1 Src Addr: "); DetectAddressPrint(global_src_gr); - //printf(" (sh %p)\n", global_src_gr->sh); - printf("\n"); + printf(" (sh %p)\n", global_src_gr->sh); + //printf("\n"); + +#ifdef PRINTSIGS + SigGroupHeadPrintSigs(de_ctx, global_src_gr->sh); + if (global_src_gr->sh != NULL) { + printf(" - "); + for (u = 0; u < global_src_gr->sh->sig_cnt; u++) { + Signature *s = de_ctx->sig_array[global_dst_gr->sh->match_array[u]]; + printf("%" PRIu32 " ", s->id); + } + printf("\n"); + } +#endif global_dst_gh = global_src_gr->dst_gh; if (global_dst_gh == NULL) @@ -2643,16 +2688,30 @@ int SigAddressPrepareStage5(DetectEngineCtx *de_ctx) { global_dst_gr = global_dst_gr->next) { printf(" 2 Dst Addr: "); DetectAddressPrint(global_dst_gr); - printf("\n"); //printf(" (sh %p) ", global_dst_gr->sh); if (global_dst_gr->sh) { if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf("(COPY)\n"); + printf(" (COPY): "); } else { - printf("\n"); + printf(" (ORIGINAL): "); } + } else { + printf(" "); } + +#ifdef PRINTSIGS + if (global_dst_gr->sh != NULL) { + printf(" - "); + for (u = 0; u < global_dst_gr->sh->sig_cnt; u++) { + Signature *s = de_ctx->sig_array[global_dst_gr->sh->match_array[u]]; + printf("%" PRIu32 " ", s->id); + } + printf("\n"); + } +#endif + + DetectPort *sp = global_dst_gr->port; for ( ; sp != NULL; sp = sp->next) { printf(" 3 Src port(range): "); DetectPortPrint(sp); diff --git a/src/detect.h b/src/detect.h index 4901b3643e..d41489b725 100644 --- a/src/detect.h +++ b/src/detect.h @@ -711,6 +711,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p); int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s); - +SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p); #endif /* __DETECT_H__ */