Fix signature grouping bug for protocols without ports. Add debugging code.

remotes/origin/master-1.0.x
Victor Julien 17 years ago
parent 7a427ec7f4
commit 46831e0f8f

@ -115,3 +115,26 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
return; 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;
}
}
}

@ -483,6 +483,8 @@ void DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t,
Packet *SetupPkt (void); Packet *SetupPkt (void);
Packet *TunnelPktSetup(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, uint8_t); Packet *TunnelPktSetup(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, uint8_t);
void AddressDebugPrint(Address *);
/** \brief Set the No payload inspection Flag for the packet. /** \brief Set the No payload inspection Flag for the packet.
* *
* \param p Packet to set the flag in * \param p Packet to set the flag in

@ -1435,27 +1435,35 @@ int DetectAddressCmp(DetectAddress *a, DetectAddress *b)
*/ */
int DetectAddressMatch(DetectAddress *dd, Address *a) int DetectAddressMatch(DetectAddress *dd, Address *a)
{ {
if (dd->family != a->family) SCEnter();
return 0;
if (dd->family != a->family) {
SCReturnInt(0);
}
//DetectAddressPrint(dd);
//AddressDebugPrint(a);
switch (a->family) { switch (a->family) {
case AF_INET: case AF_INET:
/* XXX figure out a way to not need to do this ntohl if we switch to /* 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 */ * Address inside DetectAddressData we can do uint8_t checks */
if (ntohl(a->addr_data32[0]) >= ntohl(dd->ip[0]) && if (ntohl(a->addr_data32[0]) >= ntohl(dd->ip[0]) &&
ntohl(a->addr_data32[0]) <= ntohl(dd->ip2[0])) { ntohl(a->addr_data32[0]) <= ntohl(dd->ip2[0]))
return 1; {
SCReturnInt(1);
} else { } else {
return 0; SCReturnInt(0);
} }
break; break;
case AF_INET6: case AF_INET6:
if (AddressIPv6Ge(a->addr_data32, dd->ip) == 1 && if (AddressIPv6Ge(a->addr_data32, dd->ip) == 1 &&
AddressIPv6Le(a->addr_data32, dd->ip2) == 1) { AddressIPv6Le(a->addr_data32, dd->ip2) == 1) {
return 1; SCReturnInt(1);
} else { } else {
return 0; SCReturnInt(0);
} }
break; break;
@ -1464,7 +1472,7 @@ int DetectAddressMatch(DetectAddress *dd, Address *a)
break; break;
} }
return 0; SCReturnInt(0);
} }
/** /**
@ -1520,25 +1528,33 @@ void DetectAddressPrint(DetectAddress *gr)
*/ */
DetectAddress *DetectAddressLookupInHead(DetectAddressHead *gh, Address *a) DetectAddress *DetectAddressLookupInHead(DetectAddressHead *gh, Address *a)
{ {
SCEnter();
DetectAddress *g; DetectAddress *g;
if (gh == NULL) if (gh == NULL) {
return NULL; SCReturnPtr(NULL, "DetectAddress");
}
/* XXX should we really do this check every time we run this function? */ /* 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; g = gh->ipv4_head;
else if (a->family == AF_INET6) } else if (a->family == AF_INET6) {
SCLogDebug("IPv6");
g = gh->ipv6_head; g = gh->ipv6_head;
else } else {
SCLogDebug("ANY");
g = gh->any_head; g = gh->any_head;
}
for ( ; g != NULL; g = g->next) { for ( ; g != NULL; g = g->next) {
if (DetectAddressMatch(g,a) == 1) if (DetectAddressMatch(g,a) == 1) {
return g; SCReturnPtr(g, "DetectAddress");
}
} }
return NULL; SCReturnPtr(NULL, "DetectAddress");
} }
/********************************Unittests*************************************/ /********************************Unittests*************************************/

@ -830,10 +830,10 @@ void DetectPortPrint(DetectPort *dp) {
if (dp->flags & PORT_FLAG_ANY) { if (dp->flags & PORT_FLAG_ANY) {
SCLogDebug("=> port %p: ANY", dp); SCLogDebug("=> port %p: ANY", dp);
//printf("ANY"); // printf("ANY");
} else { } else {
SCLogDebug("=> port %p %" PRIu32 "-%" PRIu32 "", dp, dp->port, dp->port2); SCLogDebug("=> port %p %" PRIu32 "-%" PRIu32 "", dp, dp->port, dp->port2);
//printf("%" PRIu32 "-%" PRIu32 "", dp->port, dp->port2); // printf("%" PRIu32 "-%" PRIu32 "", dp->port, dp->port2);
} }
} }

@ -1060,12 +1060,18 @@ void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
{ {
SCEnter(); SCEnter();
uint32_t i; if (sgh == NULL) {
SCReturn;
}
uint32_t u;
SCLogDebug("The Signatures present in this SigGroupHead are: "); SCLogDebug("The Signatures present in this SigGroupHead are: ");
for (i = 0; i < sgh->sig_size; i++) { for (u = 0; u < (sgh->sig_size * 8); u++) {
if (sgh->sig_array[i / 8] & (1 << (i % 8))) if (sgh->sig_array[u / 8] & (1 << (u % 8))) {
SCLogDebug("%" PRIu32, i); SCLogDebug("%" PRIu32, u);
printf("s->num %"PRIu16" ", u);
}
} }
SCReturn; SCReturn;
@ -1850,6 +1856,56 @@ static int SigGroupHeadTest09(void)
return result; 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 #endif
void SigGroupHeadRegisterTests(void) void SigGroupHeadRegisterTests(void)
@ -1866,6 +1922,7 @@ void SigGroupHeadRegisterTests(void)
UtRegisterTest("SigGroupHeadTest07", SigGroupHeadTest07, 1); UtRegisterTest("SigGroupHeadTest07", SigGroupHeadTest07, 1);
UtRegisterTest("SigGroupHeadTest08", SigGroupHeadTest08, 1); UtRegisterTest("SigGroupHeadTest08", SigGroupHeadTest08, 1);
UtRegisterTest("SigGroupHeadTest09", SigGroupHeadTest09, 1); UtRegisterTest("SigGroupHeadTest09", SigGroupHeadTest09, 1);
UtRegisterTest("SigGroupHeadTest10", SigGroupHeadTest10, 1);
#endif #endif

@ -76,5 +76,6 @@ int SigGroupHeadContainsSigId (DetectEngineCtx *de_ctx, SigGroupHead *sgh,
uint32_t sid); uint32_t sid);
void SigGroupHeadRegisterTests(void); void SigGroupHeadRegisterTests(void);
void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
#endif /* __DETECT_ENGINE_SIGGROUP_H__ */ #endif /* __DETECT_ENGINE_SIGGROUP_H__ */

@ -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); 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 /** \brief Create the path if default-rule-path was specified
* \param sig_file The name of the file * \param sig_file The name of the file
* \retval str Pointer to the string path + sig_file * \retval str Pointer to the string path + sig_file
@ -1135,6 +1157,7 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) {
} }
cnt++; cnt++;
} }
for (gr = tmp_s->src.ipv6_head; gr != NULL; gr = gr->next) { for (gr = tmp_s->src.ipv6_head; gr != NULL; gr = gr->next) {
if (SigGroupHeadAppendSig(de_ctx, &gr->sh, tmp_s) < 0) { if (SigGroupHeadAppendSig(de_ctx, &gr->sh, tmp_s) < 0) {
goto error; goto error;
@ -1147,6 +1170,7 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) {
} }
cnt++; cnt++;
} }
de_ctx->sig_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) { static int DetectEngineLookupDsizeAddSig(DetectEngineCtx *de_ctx, Signature *s, int family) {
SCEnter();
uint16_t low = 0, high = 65535; uint16_t low = 0, high = 65535;
if (s->flags & SIG_FLAG_DSIZE) { if (s->flags & SIG_FLAG_DSIZE) {
@ -1365,7 +1391,7 @@ static int DetectEngineLookupDsizeAddSig(DetectEngineCtx *de_ctx, Signature *s,
g_detectengine_any_big++; g_detectengine_any_big++;
} }
return 0; SCReturnInt(0);
} }
static DetectAddress *GetHeadPtr(DetectAddressHead *head, int family) { 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].tmp_gh[proto]->ipv4_head, AF_INET,
de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto], groups, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto], groups,
CreateGroupedAddrListCmpMpmMaxlen, DetectEngineGetMaxSigId(de_ctx)); CreateGroupedAddrListCmpMpmMaxlen, DetectEngineGetMaxSigId(de_ctx));
CreateGroupedAddrList(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].tmp_gh[proto]->ipv6_head, AF_INET6,
de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto], groups, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto], groups,
@ -1915,6 +1942,9 @@ error:
return -1; 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) { int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *head, int family, int dsize, int flow) {
Signature *tmp_s = NULL; Signature *tmp_s = NULL;
DetectAddress *gr = NULL, *sgr = NULL, *lookup_gr = 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 */ /* loop through the global source address list */
for (gr = grhead; gr != NULL; gr = gr->next) { 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 */ /* initialize the destination group head */
gr->dst_gh = DetectAddressHeadInit(); gr->dst_gh = DetectAddressHeadInit();
@ -1946,17 +1976,20 @@ int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *hea
continue; continue;
tmp_s = de_ctx->sig_array[sig]; tmp_s = de_ctx->sig_array[sig];
if (tmp_s == NULL) if (tmp_s == NULL)
continue; continue;
//printf(" * (tmp) Signature %u (num %u)\n", tmp_s->id, tmp_s->num);
max_idx = sig; max_idx = sig;
/* build the temp list */ /* build the temp list */
grsighead = GetHeadPtr(&tmp_s->dst, family); grsighead = GetHeadPtr(&tmp_s->dst, family);
for (sgr = grsighead; sgr != NULL; sgr = sgr->next) { 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) { if ((lookup_gr = DetectAddressLookupInList(tmp_gr_list, sgr)) == NULL) {
DetectAddress *grtmp = DetectAddressCopy(gr); DetectAddress *grtmp = DetectAddressCopy(sgr);
if (grtmp == NULL) { if (grtmp == NULL) {
goto error; goto error;
} }
@ -1984,7 +2017,7 @@ int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *hea
*/ */
grdsthead = GetHeadPtr(gr->dst_gh, family); grdsthead = GetHeadPtr(gr->dst_gh, family);
for (sgr = grdsthead; sgr != NULL; sgr = sgr->next) { 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 /* Because a pattern matcher context uses quite some
* memory, we first check if we can reuse it from * memory, we first check if we can reuse it from
@ -2086,7 +2119,8 @@ error:
return -1; 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; Signature *tmp_s = NULL;
DetectAddress *src_gr = NULL, *dst_gr = NULL, *sig_gr = NULL, *lookup_gr = 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; 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"); printf ("BuildDestinationAddressHeads(src_gh[6],AF_INET) failed\n");
goto error; goto error;
} }
//#if 0
r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[17],AF_INET,ds,f); r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[17],AF_INET,ds,f);
if (r < 0) { if (r < 0) {
printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n"); 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"); printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n");
goto error; goto error;
} }
for (proto = 0; proto < 256; proto++) { for (proto = 0; proto < 256; proto++) {
if (proto == IPPROTO_TCP || proto == IPPROTO_UDP) if (proto == IPPROTO_TCP || proto == IPPROTO_UDP)
continue; continue;
@ -2491,7 +2523,6 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) {
} }
} }
} }
//#endif
/* cleanup group head (uri)content_array's */ /* cleanup group head (uri)content_array's */
SigGroupHeadFreeMpmArrays(de_ctx); SigGroupHeadFreeMpmArrays(de_ctx);
@ -2622,17 +2653,31 @@ int SigAddressPrepareStage5(DetectEngineCtx *de_ctx) {
int ds, f, proto; int ds, f, proto;
for (ds = 0; ds < DSIZE_STATES; ds++) { for (ds = 0; ds < DSIZE_STATES; ds++) {
printf("\n");
for (f = 0; f < FLOW_STATES; f++) { for (f = 0; f < FLOW_STATES; f++) {
printf("\n");
for (proto = 0; proto < 256; proto++) { for (proto = 0; proto < 256; proto++) {
if (proto != 17) if (proto != 1)
continue; continue;
for (global_src_gr = de_ctx->dsize_gh[ds].flow_gh[f].src_gh[proto]->ipv4_head; global_src_gr != NULL; 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) global_src_gr = global_src_gr->next)
{ {
printf("1 Src Addr: "); DetectAddressPrint(global_src_gr); printf("1 Src Addr: "); DetectAddressPrint(global_src_gr);
//printf(" (sh %p)\n", global_src_gr->sh); printf(" (sh %p)\n", global_src_gr->sh);
printf("\n"); //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; global_dst_gh = global_src_gr->dst_gh;
if (global_dst_gh == NULL) if (global_dst_gh == NULL)
@ -2643,16 +2688,30 @@ int SigAddressPrepareStage5(DetectEngineCtx *de_ctx) {
global_dst_gr = global_dst_gr->next) global_dst_gr = global_dst_gr->next)
{ {
printf(" 2 Dst Addr: "); DetectAddressPrint(global_dst_gr); printf(" 2 Dst Addr: "); DetectAddressPrint(global_dst_gr);
printf("\n");
//printf(" (sh %p) ", global_dst_gr->sh); //printf(" (sh %p) ", global_dst_gr->sh);
if (global_dst_gr->sh) { if (global_dst_gr->sh) {
if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) {
printf("(COPY)\n"); printf(" (COPY): ");
} else { } 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; DetectPort *sp = global_dst_gr->port;
for ( ; sp != NULL; sp = sp->next) { for ( ; sp != NULL; sp = sp->next) {
printf(" 3 Src port(range): "); DetectPortPrint(sp); printf(" 3 Src port(range): "); DetectPortPrint(sp);

@ -711,6 +711,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Packet *p); DetectEngineThreadCtx *det_ctx, Packet *p);
int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s); int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s);
SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p);
#endif /* __DETECT_H__ */ #endif /* __DETECT_H__ */

Loading…
Cancel
Save