static int DetectEngineSMTPFiledataTest03(void) { uint8_t mimemsg1[] = {0x65, 0x76,}; uint8_t mimemsg2[] = {0x69, 0x6C,}; uint32_t mimemsg1_len = sizeof(mimemsg1) - 1; uint32_t mimemsg2_len = sizeof(mimemsg2) - 1; TcpSession ssn; Packet *p; ThreadVars th_v; DetectEngineCtx *de_ctx = NULL; DetectEngineThreadCtx *det_ctx = NULL; SMTPState *smtp_state = NULL; Flow f; int result = 1; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.proto = IPPROTO_TCP; f.flags |= FLOW_IPV4; f.alstate = SMTPStateAlloc(); MimeDecParseState *state = MimeDecInitParser(&f, NULL); ((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT; state->body_begin = 1; if (SMTPProcessDataChunk((uint8_t *)mimemsg1, sizeof(mimemsg1), state) != 0) goto end; if (SMTPProcessDataChunk((uint8_t *)mimemsg2, sizeof(mimemsg2), state) != 0) goto end; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_SMTP; StreamTcpInitConfig(TRUE); de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert smtp any any -> any any " "(msg:\"file_data smtp test\"; " "file_data; content:\"evil\"; sid:1;)"); if (de_ctx->sig_list == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = 0; r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, mimemsg1, mimemsg1_len); if (r != 0) { printf("AppLayerParse for smtp failed. Returned %d", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, mimemsg2, mimemsg2_len); if (r != 0) { printf("AppLayerParse for smtp failed. Returned %d", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); smtp_state = f.alstate; if (smtp_state == NULL) { printf("no smtp state: "); goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) { printf("sid 1 matched but shouldn't have\n"); goto end; } result = 0; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (de_ctx != NULL) SigGroupCleanup(de_ctx); if (de_ctx != NULL) SigCleanSignatures(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result == 0; }
static int XBitsTestSig01(void) { uint8_t *buf = (uint8_t *) "GET /one/ HTTP/1.1\r\n" "Host: one.example.org\r\n" "\r\n"; uint16_t buflen = strlen((char *)buf); Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; DetectEngineCtx *de_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(p, 0, SIZE_OF_PACKET); p->src.family = AF_INET; p->dst.family = AF_INET; p->payload = buf; p->payload_len = buflen; p->proto = IPPROTO_TCP; XBitsTestSetup(); de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { printf("bad de_ctx: "); goto end; } de_ctx->flags |= DE_QUIET; s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (xbits:set,abc,track ip_pair; content:\"GET \"; sid:1;)"); if (s == NULL) { printf("bad sig: "); goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); result = 1; end: if (de_ctx != NULL) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); } if (det_ctx != NULL) { DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); } if (de_ctx != NULL) { DetectEngineCtxFree(de_ctx); } XBitsTestShutdown(); SCFree(p); return result; }
/** \test multi tx google.(com|net) query matching */ static int DetectDnsQueryTest02(void) { /* google.com */ uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, }; uint8_t buf2[] = { 0x10, 0x32, /* tx id */ 0x81, 0x80, /* flags: resp, recursion desired, recusion available */ 0x00, 0x01, /* 1 query */ 0x00, 0x01, /* 1 answer */ 0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */ /* query record */ 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */ 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */ 0x00, 0x01, 0x00, 0x01, /* type a, class in */ /* answer */ 0xc0, 0x0c, /* ref to name in query above */ 0x00, 0x01, 0x00, 0x01, /* type a, class in */ 0x00, 0x01, 0x40, 0xef, /* ttl */ 0x00, 0x04, /* data len */ 0x01, 0x02, 0x03, 0x04 }; /* addr */ /* google.net */ uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x6E, 0x65, 0x74, 0x00, 0x00, 0x10, 0x00, 0x01, }; int result = 0; Flow f; DNSState *dns_state = NULL; Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; Signature *s = NULL; ThreadVars tv; DetectEngineThreadCtx *det_ctx = NULL; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&tv, 0, sizeof(ThreadVars)); memset(&f, 0, sizeof(Flow)); p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP, "192.168.1.5", "192.168.1.1", 41424, 53); p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP, "192.168.1.5", "192.168.1.1", 41424, 53); p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP, "192.168.1.5", "192.168.1.1", 41424, 53); FLOW_INITIALIZE(&f); f.flags |= FLOW_IPV4; f.proto = IPPROTO_UDP; f.protomap = FlowGetProtoMapping(f.proto); f.alproto = ALPROTO_DNS; p1->flow = &f; p1->flags |= PKT_HAS_FLOW; p1->flowflags |= FLOW_PKT_TOSERVER; p1->pcap_cnt = 1; p2->flow = &f; p2->flags |= PKT_HAS_FLOW; p2->flowflags |= FLOW_PKT_TOCLIENT; p2->pcap_cnt = 2; p3->flow = &f; p3->flags |= PKT_HAS_FLOW; p3->flowflags |= FLOW_PKT_TOSERVER; p3->pcap_cnt = 3; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->mpm_matcher = DEFAULT_MPM; de_ctx->flags |= DE_QUIET; s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google.com\"; nocase; sid:1;)"); if (s == NULL) { goto end; } s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "dns_query; content:\"google.net\"; nocase; sid:2;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf1, sizeof(buf1)); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); dns_state = f.alstate; if (dns_state == NULL) { printf("no dns state: "); goto end; } /* do detect */ SigMatchSignatures(&tv, de_ctx, det_ctx, p1); if (!(PacketAlertCheck(p1, 1))) { printf("(p1) sig 1 didn't alert, but it should have: "); goto end; } if (PacketAlertCheck(p1, 2)) { printf("(p1) sig 2 did alert, but it should not have: "); goto end; } SCMutexLock(&f.m); r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf2, sizeof(buf2)); if (r != 0) { printf("toserver client 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); /* do detect */ SigMatchSignatures(&tv, de_ctx, det_ctx, p2); if (PacketAlertCheck(p2, 1)) { printf("(p2) sig 1 alerted, but it should not have: "); goto end; } if (PacketAlertCheck(p2, 2)) { printf("(p2) sig 2 alerted, but it should not have: "); goto end; } SCMutexLock(&f.m); r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf3, sizeof(buf3)); if (r != 0) { printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); /* do detect */ SigMatchSignatures(&tv, de_ctx, det_ctx, p3); if (PacketAlertCheck(p3, 1)) { printf("(p3) sig 1 alerted, but it should not have: "); goto end; } if (!(PacketAlertCheck(p3, 2))) { printf("(p3) sig 2 didn't alert, but it should have: "); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&tv, det_ctx); if (de_ctx != NULL) SigGroupCleanup(de_ctx); if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); FLOW_DESTROY(&f); UTHFreePacket(p1); UTHFreePacket(p2); UTHFreePacket(p3); return result; }
/** * \test DetectrotoTestSetup02 is a test for a icmpv4 and icmpv6 * protocol setting up in signature. */ static int DetectProtoTestSetup02(void) { DetectProto dp; Signature *sig_icmpv4 = NULL; Signature *sig_icmpv6 = NULL; Signature *sig_icmp = NULL; DetectEngineCtx *de_ctx = NULL; int result = 0; int i; memset(&dp, 0, sizeof(dp)); if (DetectProtoInitTest(&de_ctx, &sig_icmpv4, &dp, "icmpv4") == 0) { printf("failure - imcpv4.\n"); goto end; } if (DetectProtoInitTest(&de_ctx, &sig_icmpv6, &dp, "icmpv6") == 0) { printf("failure - imcpv6.\n"); goto end; } if (DetectProtoInitTest(&de_ctx, &sig_icmp, &dp, "icmp") == 0) { printf("failure - imcp.\n"); goto end; } for (i = 0; i < 256 / 8; i++) { if (i == IPPROTO_ICMP) { if (!(sig_icmpv4->proto.proto[i / 8] & (1 << (i % 8)))) { printf("failed in sig matching - icmpv4 - icmpv4.\n"); goto end; } continue; } if (sig_icmpv4->proto.proto[i / 8] & (1 << (i % 8))) { printf("failed in sig matching - icmpv4 - others.\n"); goto end; } } for (i = 0; i < 256 / 8; i++) { if (i == IPPROTO_ICMPV6) { if (!(sig_icmpv6->proto.proto[i / 8] & (1 << (i % 8)))) { printf("failed in sig matching - icmpv6 - icmpv6.\n"); goto end; } continue; } if (sig_icmpv6->proto.proto[i / 8] & (1 << (i % 8))) { printf("failed in sig matching - icmpv6 - others.\n"); goto end; } } for (i = 0; i < 256 / 8; i++) { if (i == IPPROTO_ICMP || i == IPPROTO_ICMPV6) { if (!(sig_icmp->proto.proto[i / 8] & (1 << (i % 8)))) { printf("failed in sig matching - icmp - icmp.\n"); goto end; } continue; } if (sig_icmpv6->proto.proto[i / 8] & (1 << (i % 8))) { printf("failed in sig matching - icmp - others.\n"); goto end; } } result = 1; end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; }
/** \test Send a get request in three chunks + more data. */ static int DetectSshVersionTestDetect03(void) { int result = 0; Flow f; uint8_t sshbuf1[] = "SSH-1."; uint32_t sshlen1 = sizeof(sshbuf1) - 1; uint8_t sshbuf2[] = "7-PuTTY_2.123" ; uint32_t sshlen2 = sizeof(sshbuf2) - 1; uint8_t sshbuf3[] = "\n"; uint32_t sshlen3 = sizeof(sshbuf3) - 1; uint8_t sshbuf4[] = "whatever..."; uint32_t sshlen4 = sizeof(sshbuf4) - 1; TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_SSH; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.protoversion:2_compat; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParse(NULL, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); if (r != 0) { printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); if (r != 0) { printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); if (r != 0) { printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); SshState *ssh_state = f.alstate; if (ssh_state == NULL) { printf("no ssh state: "); goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) { printf("Error, 1.7 version is not 2 compat, so the sig should not match: "); goto end; } result = 1; end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
static int DetectThresholdTestSig3(void) { Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; int alerts = 0; struct timeval ts; DetectThresholdEntry *lookup_tsh = NULL; HostInitConfig(HOST_QUIET); memset (&ts, 0, sizeof(struct timeval)); TimeGet(&ts); memset(&th_v, 0, sizeof(th_v)); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:10;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); TimeGet(&p->ts); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); Host *host = HostLookupHostFromHash(&p->dst); if (host == NULL) { printf("host not found: "); goto cleanup; } if (!(ThresholdHostHasThreshold(host))) { HostRelease(host); printf("host has no threshold: "); goto cleanup; } HostRelease(host); TimeSetIncrementTime(200); TimeGet(&p->ts); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); host = HostLookupHostFromHash(&p->dst); if (host == NULL) { printf("host not found: "); goto cleanup; } HostRelease(host); lookup_tsh = HostGetStorageById(host, ThresholdHostStorageId()); if (lookup_tsh == NULL) { HostRelease(host); printf("lookup_tsh is NULL: "); goto cleanup; } alerts = lookup_tsh->current_count; if (alerts == 3) result = 1; else { printf("alerts %u != 3: ", alerts); goto cleanup; } cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); end: UTHFreePackets(&p, 1); HostShutdown(); return result; }
static int DetectThresholdTestSig6Ticks(void) { Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; int alerts = 0; HostInitConfig(HOST_QUIET); memset(&th_v, 0, sizeof(th_v)); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); uint64_t ticks_start = 0; uint64_t ticks_end = 0; ticks_start = UtilCpuGetTicks(); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts = PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); alerts += PacketAlertCheck(p, 1000); ticks_end = UtilCpuGetTicks(); printf("test run %"PRIu64"\n", (ticks_end - ticks_start)); if(alerts == 10) result = 1; else goto cleanup; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); end: UTHFreePackets(&p, 1); HostShutdown(); return result; }
/** \test Check the signature working to alert when http_stat_msg is used with * negated content . */ static int DetectHttpStatMsgSigTest03(void) { int result = 0; Flow f; uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; HtpState *http_state = NULL; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.proto = IPPROTO_TCP; f.flags |= FLOW_IPV4; p->flow = &f; p->flowflags |= FLOW_PKT_TOCLIENT; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_HTTP; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" "\"HTTP status message\"; content:\"ok\"; " "nocase; http_stat_msg; sid:1;)"); if (s == NULL) { goto end; } s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " "Status message nocase\"; content:!\"Not\"; " "http_stat_msg; sid:2;)"); if (s->next == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); FLOWLOCK_WRLOCK(&f); int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; FLOWLOCK_UNLOCK(&f); goto end; } r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); if (r != 0) { printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; FLOWLOCK_UNLOCK(&f); goto end; } FLOWLOCK_UNLOCK(&f); http_state = f.alstate; if (http_state == NULL) { printf("no http state: "); result = 0; goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (! PacketAlertCheck(p, 1)) { printf("sid 1 didn't matched but should have: "); goto end; } if (! PacketAlertCheck(p, 2)) { printf("sid 2 didn't matched but should have: "); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (det_ctx != NULL) { DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); } if (de_ctx != NULL) { SigGroupCleanup(de_ctx); DetectEngineCtxFree(de_ctx); } StreamTcpFreeConfig(TRUE); UTHFreePackets(&p, 1); return result; }
/** * \test Check the ftpbounce match, send a get request in three chunks * + more data. * \brief This test tests the ftpbounce condition match, based on the * ftp layer parser */ static int DetectFtpbounceTestALMatch02(void) { int result = 0; uint8_t ftpbuf1[] = { 'P','O' }; uint32_t ftplen1 = sizeof(ftpbuf1); uint8_t ftpbuf2[] = { 'R', 'T' }; uint32_t ftplen2 = sizeof(ftpbuf2); uint8_t ftpbuf3[] = { ' ', '8','0',',','5' }; uint32_t ftplen3 = sizeof(ftpbuf3); uint8_t ftpbuf4[] = "8,0,33,10,20\r\n"; uint32_t ftplen4 = sizeof(ftpbuf4); TcpSession ssn; Flow f; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacketSrcDst(NULL, 0, IPPROTO_TCP, "1.2.3.4", "5.6.7.8"); FLOW_INITIALIZE(&f); f.src.address.address_un_data32[0]=0x01020304; f.protoctx =(void *)&ssn; f.proto = IPPROTO_TCP; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_FTP; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any " "(msg:\"Ftp Bounce\"; ftpbounce; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v,(void *)de_ctx,(void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER, ftpbuf1, ftplen1); if (r != 0) { SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf2, ftplen2); if (r != 0) { SCLogDebug("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf3, ftplen3); if (r != 0) { SCLogDebug("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf4, ftplen4); if (r != 0) { SCLogDebug("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); FtpState *ftp_state = f.alstate; if (ftp_state == NULL) { SCLogDebug("no ftp state: "); result = 0; goto end; } if (ftp_state->command != FTP_COMMAND_PORT) { SCLogDebug("expected command port not detected"); result = 0; goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v,(void *)det_ctx); DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
/** \test Send a get request in three chunks + more data. */ static int DetectTlsVersionTestDetect01(void) { int result = 0; Flow f; uint8_t tlsbuf1[] = { 0x16 }; uint32_t tlslen1 = sizeof(tlsbuf1); uint8_t tlsbuf2[] = { 0x03 }; uint32_t tlslen2 = sizeof(tlsbuf2); uint8_t tlsbuf3[] = { 0x01 }; uint32_t tlslen3 = sizeof(tlsbuf3); uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x01 }; uint32_t tlslen4 = sizeof(tlsbuf4); TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_TLS; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; tls.version:1.0; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); int r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); if (r != 0) { printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); if (r != 0) { printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4); if (r != 0) { printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); goto end; } SSLState *ssl_state = f.alstate; if (ssl_state == NULL) { printf("no tls state: "); goto end; } if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, ssl_state->client_connp.content_type); goto end; } if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, ssl_state->client_connp.version); goto end; } SCLogDebug("ssl_state is at %p, ssl_state->server_version 0x%02X " "ssl_state->client_version 0x%02X", ssl_state, ssl_state->server_connp.version, ssl_state->client_connp.version); /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { goto end; } result = 1; end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
static int DetectTlsVersionTestDetect03(void) { DetectEngineCtx *de_ctx = NULL; int result = 0; Flow f; uint8_t tlsbuf1[] = { 0x16 }; uint32_t tlslen1 = sizeof(tlsbuf1); uint8_t tlsbuf2[] = { 0x03 }; uint32_t tlslen2 = sizeof(tlsbuf2); uint8_t tlsbuf3[] = { 0x01 }; uint32_t tlslen3 = sizeof(tlsbuf3); uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 }; uint32_t tlslen4 = sizeof(tlsbuf4); TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); p->tcph->th_seq = htonl(1000); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_TLS; f.proto = p->proto; StreamTcpInitConfig(TRUE); StreamMsg *stream_msg = StreamMsgGetFromPool(); if (stream_msg == NULL) { printf("no stream_msg: "); goto end; } memcpy(stream_msg->data.data, tlsbuf4, tlslen4); stream_msg->data.data_len = tlslen4; ssn.toserver_smsg_head = stream_msg; ssn.toserver_smsg_tail = stream_msg; de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"TLS\"; tls.version:1.0; content:\"|01 00 00 AD|\"; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); int r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); if (r != 0) { printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); if (r != 0) { printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); goto end; } r = AppLayerParse(NULL, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4); if (r != 0) { printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); goto end; } SSLState *ssl_state = f.alstate; if (ssl_state == NULL) { printf("no tls state: "); goto end; } if (ssl_state->client_connp.content_type != 0x16) { printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, ssl_state->client_connp.content_type); goto end; } if (ssl_state->client_connp.version != TLS_VERSION_10) { printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, ssl_state->client_connp.version); goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { printf("signature 1 didn't match while it should have: "); goto end; } result = 1; end: if (de_ctx != NULL) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); } StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
/** * \internal * \brief This test tests sameip success and failure. */ static int DetectSameipSigTest01Real(int mpm_type) { uint8_t *buf = (uint8_t *) "GET / HTTP/1.0\r\n" "\r\n"; uint16_t buflen = strlen((char *)buf); Packet *p1 = NULL; Packet *p2 = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; memset(&th_v, 0, sizeof(th_v)); /* First packet has same IPs */ p1 = UTHBuildPacketSrcDst(buf, buflen, IPPROTO_TCP, "1.2.3.4", "1.2.3.4"); /* Second packet does not have same IPs */ p2 = UTHBuildPacketSrcDst(buf, buflen, IPPROTO_TCP, "1.2.3.4", "4.3.2.1"); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->mpm_matcher = mpm_type; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing sameip\"; sameip; sid:1;)"); if (de_ctx->sig_list == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); if (PacketAlertCheck(p1, 1) == 0) { printf("sid 2 did not alert, but should have: "); goto cleanup; } SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); if (PacketAlertCheck(p2, 1) != 0) { printf("sid 2 alerted, but should not have: "); goto cleanup; } result = 1; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); end: return result; }
/** * \test DetectIcmpIdMatchTest02 is a test for checking the working of * icmp_id keyword by creating 1 rule and matching a crafted packet * against them. The packet is an ICMP packet with no "id" field, * therefore the rule should not trigger. */ int DetectIcmpIdMatchTest02 (void) { int result = 0; uint8_t raw_icmpv4[] = { 0x0b, 0x00, 0x8a, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x14, 0x25, 0x0c, 0x00, 0x00, 0xff, 0x11, 0x00, 0x00, 0x85, 0x64, 0xea, 0x5b, 0x51, 0xa6, 0xbb, 0x35, 0x59, 0x8a, 0x5a, 0xe2, 0x00, 0x14, 0x00, 0x00 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) return 0; Signature *s = NULL; DecodeThreadVars dtv; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; IPV4Hdr ip4h; memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&ip4h, 0, sizeof(IPV4Hdr)); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&th_v, 0, sizeof(ThreadVars)); FlowInitConfig(FLOW_QUIET); p->src.addr_data32[0] = 0x01020304; p->dst.addr_data32[0] = 0x04030201; ip4h.ip_src.s_addr = p->src.addr_data32[0]; ip4h.ip_dst.s_addr = p->dst.addr_data32[0]; p->ip4h = &ip4h; DecodeICMPV4(&th_v, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (icmp_id:0; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) { printf("sid 1 alerted, but should not have: "); goto cleanup; } result = 1; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); FlowShutdown(); end: SCFree(p); return result; }
int main(int argc, char **argv) { int opt; char *pcap_file = NULL; char pcap_dev[128]; #ifdef HAVE_PFRING char *pfring_dev = NULL; #endif char *sig_file = NULL; char *nfq_id = NULL; char *conf_filename = NULL; char *pid_filename = NULL; #ifdef UNITTESTS char *regex_arg = NULL; #endif int dump_config = 0; int list_unittests = 0; int list_cuda_cards = 0; int daemon = 0; char *user_name = NULL; char *group_name = NULL; uint8_t do_setuid = FALSE; uint8_t do_setgid = FALSE; uint32_t userid = 0; uint32_t groupid = 0; char *erf_file = NULL; char *dag_input = NULL; char *log_dir; struct stat buf; sc_set_caps = FALSE; SC_ATOMIC_INIT(engine_stage); /* initialize the logging subsys */ SCLogInitLogModule(NULL); /* By default use IDS mode, but if nfq or ipfw * are specified, IPS mode will overwrite this */ SET_ENGINE_MODE_IDS(engine_mode); #ifdef OS_WIN32 /* service initialization */ if (SCRunningAsService()) { char path[MAX_PATH]; char *p = NULL; strlcpy(path, argv[0], MAX_PATH); if ((p = strrchr(path, '\\'))) { *p = '\0'; } if (!SetCurrentDirectory(path)) { SCLogError(SC_ERR_FATAL, "Can't set current directory to: %s", path); return -1; } SCLogInfo("Current directory is set to: %s", path); daemon = 1; SCServiceInit(argc, argv); } /* Windows socket subsystem initialization */ WSADATA wsaData; if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { SCLogError(SC_ERR_FATAL, "Can't initialize Windows sockets: %d", WSAGetLastError()); exit(EXIT_FAILURE); } #endif /* OS_WIN32 */ #ifdef REVISION SCLogInfo("This is %s version %s (rev %s)", PROG_NAME, PROG_VER, xstr(REVISION)); #else SCLogInfo("This is %s version %s", PROG_NAME, PROG_VER); #endif /* Initialize the configuration module. */ ConfInit(); struct option long_opts[] = { {"dump-config", 0, &dump_config, 1}, {"pfring-int", required_argument, 0, 0}, {"pfring-cluster-id", required_argument, 0, 0}, {"pfring-cluster-type", required_argument, 0, 0}, {"pcap-buffer-size", required_argument, 0, 0}, {"unittest-filter", required_argument, 0, 'U'}, {"list-unittests", 0, &list_unittests, 1}, {"list-cuda-cards", 0, &list_cuda_cards, 1}, {"engine-analysis", 0, &engine_analysis, 1}, #ifdef OS_WIN32 {"service-install", 0, 0, 0}, {"service-remove", 0, 0, 0}, {"service-change-params", 0, 0, 0}, #endif /* OS_WIN32 */ {"pidfile", required_argument, 0, 0}, {"init-errors-fatal", 0, 0, 0}, {"fatal-unittests", 0, 0, 0}, {"user", required_argument, 0, 0}, {"group", required_argument, 0, 0}, {"erf-in", required_argument, 0, 0}, {"dag", required_argument, 0, 0}, {NULL, 0, NULL, 0} }; /* getopt_long stores the option index here. */ int option_index = 0; char short_opts[] = "c:Dhi:l:q:d:r:us:U:V"; while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) { switch (opt) { case 0: if(strcmp((long_opts[option_index]).name , "pfring-int") == 0){ #ifdef HAVE_PFRING run_mode = MODE_PFRING; if (ConfSet("pfring.interface", optarg, 0) != 1) { fprintf(stderr, "ERROR: Failed to set pfring interface.\n"); exit(EXIT_FAILURE); } #else SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure to pass --enable-pfring to configure when building."); exit(EXIT_FAILURE); #endif /* HAVE_PFRING */ } else if(strcmp((long_opts[option_index]).name , "pfring-cluster-id") == 0){ #ifdef HAVE_PFRING if (ConfSet("pfring.cluster-id", optarg, 0) != 1) { fprintf(stderr, "ERROR: Failed to set pfring cluster-id.\n"); exit(EXIT_FAILURE); } #else SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure to pass --enable-pfring to configure when building."); exit(EXIT_FAILURE); #endif /* HAVE_PFRING */ } else if(strcmp((long_opts[option_index]).name , "pfring-cluster-type") == 0){ #ifdef HAVE_PFRING if (ConfSet("pfring.cluster-type", optarg, 0) != 1) { fprintf(stderr, "ERROR: Failed to set pfring cluster-type.\n"); exit(EXIT_FAILURE); } #else SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure to pass --enable-pfring to configure when building."); exit(EXIT_FAILURE); #endif /* HAVE_PFRING */ } else if(strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) { if (ConfSet("engine.init_failure_fatal", "1", 0) != 1) { fprintf(stderr, "ERROR: Failed to set engine init_failure_fatal.\n"); exit(EXIT_FAILURE); } } else if(strcmp((long_opts[option_index]).name, "list-unittests") == 0) { #ifdef UNITTESTS /* Set run_mode to unit tests. */ run_mode = MODE_UNITTEST; #else fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); exit(EXIT_FAILURE); #endif /* UNITTESTS */ } else if(strcmp((long_opts[option_index]).name, "list-cuda-cards") == 0) { #ifndef __SC_CUDA_SUPPORT__ fprintf(stderr, "ERROR: Cuda not enabled. Make sure to pass " "--enable-cuda to configure when building.\n"); exit(EXIT_FAILURE); #endif /* UNITTESTS */ } else if(strcmp((long_opts[option_index]).name, "engine-analysis") == 0) { // do nothing for now } #ifdef OS_WIN32 else if(strcmp((long_opts[option_index]).name, "service-install") == 0) { if (SCServiceInstall(argc, argv)) { exit(EXIT_FAILURE); } SCLogInfo("Suricata service has been successfuly installed."); exit(EXIT_SUCCESS); } else if(strcmp((long_opts[option_index]).name, "service-remove") == 0) { if (SCServiceRemove(argc, argv)) { exit(EXIT_FAILURE); } SCLogInfo("Suricata service has been successfuly removed."); exit(EXIT_SUCCESS); } else if(strcmp((long_opts[option_index]).name, "service-change-params") == 0) { if (SCServiceChangeParams(argc, argv)) { exit(EXIT_FAILURE); } SCLogInfo("Suricata service startup parameters has been successfuly changed."); exit(EXIT_SUCCESS); } #endif /* OS_WIN32 */ else if(strcmp((long_opts[option_index]).name, "pidfile") == 0) { pid_filename = optarg; } else if(strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) { #ifdef UNITTESTS if (ConfSet("unittests.failure_fatal", "1", 0) != 1) { fprintf(stderr, "ERROR: Failed to set unittests failure_fatal.\n"); exit(EXIT_FAILURE); } #else fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); exit(EXIT_FAILURE); #endif /* UNITTESTS */ } else if(strcmp((long_opts[option_index]).name, "user") == 0) { #ifndef HAVE_LIBCAP_NG SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to" " drop privileges, but it was not compiled into Suricata."); exit(EXIT_FAILURE); #else user_name = optarg; do_setuid = TRUE; #endif /* HAVE_LIBCAP_NG */ } else if(strcmp((long_opts[option_index]).name, "group") == 0) { #ifndef HAVE_LIBCAP_NG SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to" " drop privileges, but it was not compiled into Suricata."); exit(EXIT_FAILURE); #else group_name = optarg; do_setgid = TRUE; #endif /* HAVE_LIBCAP_NG */ } else if (strcmp((long_opts[option_index]).name, "erf-in") == 0) { run_mode = MODE_ERF_FILE; erf_file = optarg; } else if (strcmp((long_opts[option_index]).name, "dag") == 0) { #ifdef HAVE_DAG run_mode = MODE_DAG; dag_input = optarg; #else SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required" " to receieve packets using --dag."); exit(EXIT_FAILURE); #endif /* HAVE_DAG */ } else if(strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) { #ifdef HAVE_PCAP_SET_BUFF if (ConfSet("pcap.buffer-size", optarg, 0) != 1) { fprintf(stderr, "ERROR: Failed to set pcap-buffer-size.\n"); exit(EXIT_FAILURE); } #else SCLogError(SC_ERR_NO_PCAP_SET_BUFFER_SIZE, "The version of libpcap you have" " doesn't support setting buffer size."); #endif /* HAVE_PCAP_SET_BUFF */ } break; case 'c': conf_filename = optarg; break; #ifndef OS_WIN32 case 'D': daemon = 1; break; #endif /* OS_WIN32 */ case 'h': usage(argv[0]); exit(EXIT_SUCCESS); break; case 'i': if (run_mode == MODE_UNKNOWN) { run_mode = MODE_PCAP_DEV; PcapLiveRegisterDevice(optarg); } else if (run_mode == MODE_PCAP_DEV) { #ifdef OS_WIN32 SCLogError(SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT, "pcap multi dev " "support is not (yet) supported on Windows."); exit(EXIT_FAILURE); #else SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " "multiple pcap devices to get packets is experimental."); PcapLiveRegisterDevice(optarg); #endif } else { SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " "has been specified"); usage(argv[0]); exit(EXIT_FAILURE); } memset(pcap_dev, 0, sizeof(pcap_dev)); strlcpy(pcap_dev, optarg, ((strlen(optarg) < sizeof(pcap_dev)) ? (strlen(optarg)+1) : (sizeof(pcap_dev)))); break; case 'l': if (ConfSet("default-log-dir", optarg, 0) != 1) { fprintf(stderr, "ERROR: Failed to set log directory.\n"); exit(EXIT_FAILURE); } if (stat(optarg, &buf) != 0) { SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\" " "supplied at the commandline (-l %s) doesn't " "exist. Shutting down the engine.", optarg, optarg); exit(EXIT_FAILURE); } break; case 'q': #ifdef NFQ if (run_mode == MODE_UNKNOWN) { run_mode = MODE_NFQ; SET_ENGINE_MODE_IPS(engine_mode); if (NFQRegisterQueue(optarg) == -1) exit(EXIT_FAILURE); } else if (run_mode == MODE_NFQ) { if (NFQRegisterQueue(optarg) == -1) exit(EXIT_FAILURE); } else { SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " "has been specified"); usage(argv[0]); exit(EXIT_FAILURE); } nfq_id = optarg; #else SCLogError(SC_ERR_NFQ_NOSUPPORT,"NFQUEUE not enabled. Make sure to pass --enable-nfqueue to configure when building."); exit(EXIT_FAILURE); #endif /* NFQ */ break; case 'd': #ifdef IPFW if (run_mode == MODE_UNKNOWN) { run_mode = MODE_IPFW; SET_ENGINE_MODE_IPS(engine_mode); } else { SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " "has been specified"); usage(argv[0]); exit(EXIT_SUCCESS); } if (ConfSet("ipfw-divert-port", optarg, 0) != 1) { fprintf(stderr, "ERROR: Failed to set ipfw_divert_port\n"); exit(EXIT_FAILURE); } #else SCLogError(SC_ERR_IPFW_NOSUPPORT,"IPFW not enabled. Make sure to pass --enable-ipfw to configure when building."); exit(EXIT_FAILURE); #endif /* IPFW */ break; case 'r': if (run_mode == MODE_UNKNOWN) { run_mode = MODE_PCAP_FILE; } else { SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " "has been specified"); usage(argv[0]); exit(EXIT_SUCCESS); } pcap_file = optarg; break; case 's': sig_file = optarg; break; case 'u': #ifdef UNITTESTS if (run_mode == MODE_UNKNOWN) { run_mode = MODE_UNITTEST; } else { SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode has" " been specified"); usage(argv[0]); exit(EXIT_SUCCESS); } #else fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); exit(EXIT_FAILURE); #endif /* UNITTESTS */ break; case 'U': #ifdef UNITTESTS regex_arg = optarg; if(strlen(regex_arg) == 0) regex_arg = NULL; #endif break; case 'V': #ifdef REVISION printf("\nThis is %s version %s (rev %s)\n\n", PROG_NAME, PROG_VER, xstr(REVISION)); #else printf("\nThis is %s version %s\n\n", PROG_NAME, PROG_VER); #endif exit(EXIT_SUCCESS); default: usage(argv[0]); exit(EXIT_FAILURE); } } SetBpfString(optind, argv); UtilCpuPrintSummary(); #ifdef __SC_CUDA_SUPPORT__ /* Init the CUDA environment */ SCCudaInitCudaEnvironment(); if (list_cuda_cards) { SCCudaListCards(); exit(EXIT_SUCCESS); } #endif if (!CheckValidDaemonModes(daemon, run_mode)) { exit(EXIT_FAILURE); } /* Initializations for global vars, queues, etc (memsets, mutex init..) */ GlobalInits(); TimeInit(); SupportFastPatternForSigMatchTypes(); /* Load yaml configuration file if provided. */ if (conf_filename != NULL) { if (ConfYamlLoadFile(conf_filename) != 0) { /* Error already displayed. */ exit(EXIT_FAILURE); } } else if (run_mode != MODE_UNITTEST){ SCLogError(SC_ERR_OPENING_FILE, "Configuration file has not been provided"); usage(argv[0]); exit(EXIT_FAILURE); } if (dump_config) { ConfDump(); exit(EXIT_SUCCESS); } /* Check for the existance of the default logging directory which we pick * from suricata.yaml. If not found, shut the engine down */ if (ConfGet("default-log-dir", &log_dir) != 1) log_dir = DEFAULT_LOG_DIR; if (stat(log_dir, &buf) != 0) { SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" " "supplied by %s (default-log-dir) doesn't exist. " "Shutting down the engine", log_dir, conf_filename); exit(EXIT_FAILURE); } /* Pull the max pending packets from the config, if not found fall * back on a sane default. */ if (ConfGetInt("max-pending-packets", &max_pending_packets) != 1) max_pending_packets = DEFAULT_MAX_PENDING_PACKETS; SCLogDebug("Max pending packets set to %"PRIiMAX, max_pending_packets); /* Pull the default packet size from the config, if not found fall * back on a sane default. */ if (ConfGetInt("default-packet-size", &default_packet_size) != 1) { switch (run_mode) { case MODE_PCAP_DEV: case MODE_PFRING: /* find payload for interface and use it */ default_packet_size = GetIfaceMaxPayloadSize(pcap_dev); if (default_packet_size) break; default: default_packet_size = DEFAULT_PACKET_SIZE; } } SCLogDebug("Default packet size set to %"PRIiMAX, default_packet_size); #ifdef NFQ if (run_mode == MODE_NFQ) NFQInitConfig(FALSE); #endif /* Since our config is now loaded we can finish configurating the * logging module. */ SCLogLoadConfig(); #ifdef __SC_CUDA_SUPPORT__ /* load the cuda configuration */ SCCudaHlGetYamlConf(); #endif /* __SC_CUDA_SUPPORT__ */ /* Load the Host-OS lookup. */ SCHInfoLoadFromConfig(); if (run_mode == MODE_UNKNOWN) { if (!engine_analysis) { usage(argv[0]); exit(EXIT_FAILURE); } } if (engine_analysis) { SCLogInfo("== Carrying out Engine Analysis =="); char *temp = NULL; if (ConfGet("engine-analysis", &temp) == 0) { SCLogInfo("no engine-analysis parameter(s) defined in conf file. " "Please define/enable them in the conf to use this " "feature."); exit(EXIT_FAILURE); } } /* create table for O(1) lowercase conversion lookup. It was removed, but * we still need it for cuda. So resintalling it back into the codebase */ uint8_t c = 0; memset(g_u8_lowercasetable, 0x00, sizeof(g_u8_lowercasetable)); for ( ; c < 255; c++) { if (c >= 'A' && c <= 'Z') g_u8_lowercasetable[c] = (c + ('a' - 'A')); else g_u8_lowercasetable[c] = c; } /* hardcoded initialization code */ MpmTableSetup(); /* load the pattern matchers */ SigTableSetup(); /* load the rule keywords */ TmqhSetup(); CIDRInit(); SigParsePrepare(); //PatternMatchPrepare(mpm_ctx, MPM_B2G); SCPerfInitCounterApi(); #ifdef PROFILING SCProfilingInit(); #endif /* PROFILING */ SCReputationInitCtx(); SCProtoNameInit(); TagInitCtx(); TmModuleReceiveNFQRegister(); TmModuleVerdictNFQRegister(); TmModuleDecodeNFQRegister(); TmModuleReceiveIPFWRegister(); TmModuleVerdictIPFWRegister(); TmModuleDecodeIPFWRegister(); TmModuleReceivePcapRegister(); TmModuleDecodePcapRegister(); TmModuleReceivePfringRegister(); TmModuleDecodePfringRegister(); TmModuleReceivePcapFileRegister(); TmModuleDecodePcapFileRegister(); TmModuleDetectRegister(); TmModuleAlertFastLogRegister(); TmModuleAlertDebugLogRegister(); TmModuleAlertPreludeRegister(); TmModuleRespondRejectRegister(); TmModuleAlertFastLogIPv4Register(); TmModuleAlertFastLogIPv6Register(); TmModuleAlertSyslogIPv4Register(); TmModuleAlertSyslogIPv6Register(); TmModuleAlertUnifiedLogRegister(); TmModuleAlertUnifiedAlertRegister(); TmModuleUnified2AlertRegister(); TmModuleAlertSyslogRegister(); TmModuleLogDropLogRegister(); TmModuleStreamTcpRegister(); TmModuleLogHttpLogRegister(); TmModuleLogHttpLogIPv4Register(); TmModuleLogHttpLogIPv6Register(); #ifdef __SC_CUDA_SUPPORT__ TmModuleCudaMpmB2gRegister(); TmModuleCudaPacketBatcherRegister(); #endif TmModuleReceiveErfFileRegister(); TmModuleDecodeErfFileRegister(); TmModuleReceiveErfDagRegister(); TmModuleDecodeErfDagRegister(); TmModuleDebugList(); /** \todo we need an api for these */ AppLayerDetectProtoThreadInit(); RegisterAppLayerParsers(); RegisterHTPParsers(); RegisterTLSParsers(); RegisterSMBParsers(); RegisterDCERPCParsers(); RegisterDCERPCUDPParsers(); RegisterFTPParsers(); RegisterSSHParsers(); AppLayerParsersInitPostProcess(); #ifdef UNITTESTS if (run_mode == MODE_UNITTEST) { #ifdef DBG_MEM_ALLOC SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem); #endif /* test and initialize the unittesting subsystem */ if(regex_arg == NULL){ regex_arg = ".*"; UtRunSelftest(regex_arg); /* inits and cleans up again */ } AppLayerHtpEnableRequestBodyCallback(); AppLayerHtpRegisterExtraCallbacks(); UtInitialize(); UTHRegisterTests(); SCReputationRegisterTests(); TmModuleRegisterTests(); SigTableRegisterTests(); HashTableRegisterTests(); HashListTableRegisterTests(); BloomFilterRegisterTests(); BloomFilterCountingRegisterTests(); PoolRegisterTests(); ByteRegisterTests(); MpmRegisterTests(); FlowBitRegisterTests(); FlowAlertSidRegisterTests(); SCPerfRegisterTests(); DecodePPPRegisterTests(); DecodeVLANRegisterTests(); HTPParserRegisterTests(); TLSParserRegisterTests(); SSHParserRegisterTests(); SMBParserRegisterTests(); DCERPCParserRegisterTests(); DCERPCUDPParserRegisterTests(); FTPParserRegisterTests(); DecodeRawRegisterTests(); DecodePPPOERegisterTests(); DecodeICMPV4RegisterTests(); DecodeICMPV6RegisterTests(); DecodeIPV4RegisterTests(); DecodeTCPRegisterTests(); DecodeUDPV4RegisterTests(); DecodeGRERegisterTests(); DecodeAsn1RegisterTests(); AlpDetectRegisterTests(); ConfRegisterTests(); ConfYamlRegisterTests(); TmqhFlowRegisterTests(); FlowRegisterTests(); SCSigRegisterSignatureOrderingTests(); SCRadixRegisterTests(); DefragRegisterTests(); SigGroupHeadRegisterTests(); SCHInfoRegisterTests(); SCRuleVarsRegisterTests(); AppLayerParserRegisterTests(); ThreadMacrosRegisterTests(); UtilSpmSearchRegistertests(); UtilActionRegisterTests(); SCClassConfRegisterTests(); SCThresholdConfRegisterTests(); SCRConfRegisterTests(); #ifdef __SC_CUDA_SUPPORT__ SCCudaRegisterTests(); #endif PayloadRegisterTests(); DcePayloadRegisterTests(); UriRegisterTests(); #ifdef PROFILING SCProfilingRegisterTests(); #endif DeStateRegisterTests(); DetectRingBufferRegisterTests(); MemcmpRegisterTests(); DetectEngineHttpClientBodyRegisterTests(); DetectEngineHttpHeaderRegisterTests(); DetectEngineHttpRawHeaderRegisterTests(); DetectEngineHttpMethodRegisterTests(); DetectEngineHttpCookieRegisterTests(); DetectEngineRegisterTests(); SCLogRegisterTests(); if (list_unittests) { UtListTests(regex_arg); } else { uint32_t failed = UtRunTests(regex_arg); UtCleanup(); #ifdef __SC_CUDA_SUPPORT__ /* need this in case any of the cuda dispatcher threads are still * running, kill them, so that we can free the cuda contexts. We * need to free those cuda contexts so that next when we call * deregister functions, we will need to attach to those contexts * the contexts and its associated data */ TmThreadKillThreads(); SCCudaHlDeRegisterAllRegisteredModules(); #endif if (failed) { exit(EXIT_FAILURE); } } #ifdef DBG_MEM_ALLOC SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem); #endif exit(EXIT_SUCCESS); } #endif /* UNITTESTS */ if (daemon == 1) { Daemonize(); if (pid_filename != NULL) { if (SCPidfileCreate(pid_filename) != 0) { pid_filename = NULL; exit(EXIT_FAILURE); } } } else { if (pid_filename != NULL) { SCLogError(SC_ERR_PIDFILE_DAEMON, "The pidfile file option applies " "only to the daemon modes"); pid_filename = NULL; exit(EXIT_FAILURE); } } /* registering signals we use */ SignalHandlerSetup(SIGINT, SignalHandlerSigint); SignalHandlerSetup(SIGTERM, SignalHandlerSigterm); #ifndef OS_WIN32 /* SIGHUP is not implemnetd on WIN32 */ //SignalHandlerSetup(SIGHUP, SignalHandlerSighup); /* Get the suricata user ID to given user ID */ if (do_setuid == TRUE) { if (SCGetUserID(user_name, group_name, &userid, &groupid) != 0) { SCLogError(SC_ERR_UID_FAILED, "failed in getting user ID"); exit(EXIT_FAILURE); } sc_set_caps = TRUE; /* Get the suricata group ID to given group ID */ } else if (do_setgid == TRUE) { if (SCGetGroupID(group_name, &groupid) != 0) { SCLogError(SC_ERR_GID_FAILED, "failed in getting group ID"); exit(EXIT_FAILURE); } sc_set_caps = TRUE; } #endif /* OS_WIN32 */ /* pre allocate packets */ SCLogDebug("preallocating packets... packet size %" PRIuMAX "", (uintmax_t)SIZE_OF_PACKET); int i = 0; for (i = 0; i < max_pending_packets; i++) { /* XXX pkt alloc function */ Packet *p = SCMalloc(SIZE_OF_PACKET); if (p == NULL) { SCLogError(SC_ERR_FATAL, "Fatal error encountered while allocating a packet. Exiting..."); exit(EXIT_FAILURE); } PACKET_INITIALIZE(p); PacketPoolStorePacket(p); } SCLogInfo("preallocated %"PRIiMAX" packets. Total memory %"PRIuMAX"", max_pending_packets, (uintmax_t)(max_pending_packets*SIZE_OF_PACKET)); FlowInitConfig(FLOW_VERBOSE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); SCClassConfLoadClassficationConfigFile(de_ctx); SCRConfLoadReferenceConfigFile(de_ctx); ActionInitConfig(); if (SigLoadSignatures(de_ctx, sig_file) < 0) { if (sig_file == NULL) { SCLogError(SC_ERR_OPENING_FILE, "Signature file has not been provided"); } else { SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed."); } if (de_ctx->failure_fatal) exit(EXIT_FAILURE); } if (engine_analysis) { exit(EXIT_SUCCESS); } #ifdef PROFILING SCProfilingInitRuleCounters(de_ctx); #endif /* PROFILING */ #ifdef __SC_CUDA_SUPPORT__ SCCudaPBSetUpQueuesAndBuffers(); #endif /* __SC_CUDA_SUPPORT__ */ AppLayerHtpRegisterExtraCallbacks(); SCThresholdConfInitContext(de_ctx,NULL); SCAsn1LoadConfig(); struct timeval start_time; memset(&start_time, 0, sizeof(start_time)); gettimeofday(&start_time, NULL); SCDropMainThreadCaps(userid, groupid); RunModeInitializeOutputs(); /* run the selected runmode */ if (run_mode == MODE_PCAP_DEV) { //RunModeIdsPcap3(de_ctx, pcap_dev); //RunModeIdsPcap2(de_ctx, pcap_dev); //RunModeIdsPcap(de_ctx, pcap_dev); PcapTranslateIPToDevice(pcap_dev, sizeof(pcap_dev)); RunModeIdsPcapAuto(de_ctx, pcap_dev); } else if (run_mode == MODE_PCAP_FILE) { //RunModeFilePcap(de_ctx, pcap_file); //RunModeFilePcap2(de_ctx, pcap_file); RunModeFilePcapAuto(de_ctx, pcap_file); //RunModeFilePcapAutoFp(de_ctx, pcap_file); //RunModeFilePcapAuto2(de_ctx, pcap_file); } #ifdef HAVE_PFRING else if (run_mode == MODE_PFRING) { PfringLoadConfig(); //RunModeIdsPfring3(de_ctx, pfring_dev); //RunModeIdsPfring2(de_ctx, pfring_dev); //RunModeIdsPfring(de_ctx, pfring_dev); //RunModeIdsPfring4(de_ctx, pfring_dev); if (PfringConfGetThreads() == 1) { RunModeIdsPfringAuto(de_ctx, pfring_dev); } else { RunModeIdsPfringAutoFp(de_ctx, pfring_dev); } } #endif /* HAVE_PFRING */ else if (run_mode == MODE_NFQ) { //RunModeIpsNFQ(de_ctx, nfq_id); RunModeIpsNFQAuto(de_ctx, nfq_id); } else if (run_mode == MODE_IPFW) { //RunModeIpsIPFW(de_ctx); RunModeIpsIPFWAuto(de_ctx); } else if (run_mode == MODE_ERF_FILE) { RunModeErfFileAuto(de_ctx, erf_file); } else if (run_mode == MODE_DAG) { RunModeErfDagAuto(de_ctx, dag_input); } else { SCLogError(SC_ERR_UNKNOWN_RUN_MODE, "Unknown runtime mode. Aborting"); exit(EXIT_FAILURE); } #ifdef __SC_CUDA_SUPPORT__ if (PatternMatchDefaultMatcher() == MPM_B2G_CUDA) { /* start the dispatcher thread for this module */ if (B2gCudaStartDispatcherThreadRC("SC_RULES_CONTENT_B2G_CUDA") == -1) exit(EXIT_FAILURE); } #endif /* Spawn the flow manager thread */ FlowManagerThreadSpawn(); StreamTcpInitConfig(STREAM_VERBOSE); DefragInit(); /* Spawn the L7 App Detect thread */ //AppLayerDetectProtoThreadSpawn(); /* Spawn the perf counter threads. Let these be the last one spawned */ SCPerfSpawnThreads(); /* Check if the alloted queues have at least 1 reader and writer */ TmValidateQueueState(); /* Wait till all the threads have been initialized */ if (TmThreadWaitOnThreadInit() == TM_ECODE_FAILED) { SCLogError(SC_ERR_INITIALIZATION, "Engine initialization failed, " "aborting..."); exit(EXIT_FAILURE); } SC_ATOMIC_CAS(&engine_stage, SURICATA_INIT, SURICATA_RUNTIME); /* Un-pause all the paused threads */ TmThreadContinueThreads(); #ifdef DBG_MEM_ALLOC SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem); #ifdef DBG_MEM_ALLOC_SKIP_STARTUP print_mem_flag = 1; #endif #endif while(1) { if (suricata_ctl_flags != 0) { SCLogInfo("signal received"); if (suricata_ctl_flags & SURICATA_STOP) { SCLogInfo("EngineStop received"); /* Stop the engine so it quits after processing the pcap file * but first make sure all packets are processed by all other * threads. */ char done = 0; do { if (suricata_ctl_flags & SURICATA_KILL) break; /* if all packets are returned to the packetpool * we are done */ if (PacketPoolSize() == max_pending_packets) done = 1; if (done == 0) { usleep(100); } } while (done == 0); SCLogInfo("all packets processed by threads, stopping engine"); } struct timeval end_time; memset(&end_time, 0, sizeof(end_time)); gettimeofday(&end_time, NULL); SCLogInfo("time elapsed %" PRIuMAX "s", (uintmax_t)(end_time.tv_sec - start_time.tv_sec)); #ifdef __SC_CUDA_SUPPORT__ SCCudaPBKillBatchingPackets(); #endif TmThreadKillThreads(); SCPerfReleaseResources(); break; } TmThreadCheckThreadState(); usleep(10* 1000); } /* Update the engine stage/status flag */ SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT); FlowShutdown(); FlowPrintQueueInfo(); StreamTcpFreeConfig(STREAM_VERBOSE); HTPFreeConfig(); HTPAtExitPrintStats(); #ifdef DBG_MEM_ALLOC SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem); #ifdef DBG_MEM_ALLOC_SKIP_STARTUP print_mem_flag = 0; #endif #endif SCPidfileRemove(pid_filename); /** \todo review whats needed here */ #ifdef __SC_CUDA_SUPPORT__ if (PatternMatchDefaultMatcher() == MPM_B2G_CUDA) { /* all threadvars related to cuda should be free by now, which means * the cuda contexts would be floating */ if (SCCudaHlPushCudaContextFromModule("SC_RULES_CONTENT_B2G_CUDA") == -1) { SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Call to " "SCCudaHlPushCudaContextForModule() failed during the " "shutdown phase just before the call to SigGroupCleanup()"); } } #endif SigGroupCleanup(de_ctx); #ifdef __SC_CUDA_SUPPORT__ if (PatternMatchDefaultMatcher() == MPM_B2G_CUDA) { /* pop the cuda context we just pushed before the call to SigGroupCleanup() */ if (SCCudaCtxPopCurrent(NULL) == -1) { SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Call to SCCudaCtxPopCurrent() " "during the shutdown phase just before the call to " "SigGroupCleanup()"); return 0; } } #endif AppLayerHtpPrintStats(); SigCleanSignatures(de_ctx); if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { MpmFactoryDeRegisterAllMpmCtxProfiles(); } DetectEngineCtxFree(de_ctx); AlpProtoDestroy(); TagDestroyCtx(); RunModeShutDown(); OutputDeregisterAll(); TimeDeinit(); SCProtoNameDeInit(); DefragDestroy(); TmqhPacketpoolDestroy(); #ifdef PROFILING if (profiling_rules_enabled) SCProfilingDump(stdout); SCProfilingDestroy(); #endif #ifdef __SC_CUDA_SUPPORT__ /* all cuda contexts attached to any threads should be free by now. * if any host_thread is still attached to any cuda_context, they need * to pop them by the time we reach here, if they aren't using those * cuda contexts in any way */ SCCudaHlDeRegisterAllRegisteredModules(); #endif #ifdef OS_WIN32 if (daemon) { return 0; } #endif /* OS_WIN32 */ SC_ATOMIC_DESTROY(engine_stage); exit(EXIT_SUCCESS); }
/** \brief test if the action is alert then packet shouldn't be logged */ int LogDropLogTest02() { int result = 0; EngineModeSetIPS(); uint8_t *buf = (uint8_t *) "GET"; uint16_t buflen = strlen((char *)buf); Packet *p = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; LogDropLogThread dlt; LogFileCtx *logfile_ctx = LogFileNewCtx(); if (logfile_ctx == NULL) { printf("Could not create new LogFileCtx\n"); return 0; } memset (&dlt, 0, sizeof(LogDropLogThread)); dlt.file_ctx = logfile_ctx; dlt.file_ctx->fp = stdout; memset(&th_v, 0, sizeof(th_v)); p = UTHBuildPacket(buf, buflen, IPPROTO_UDP); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { return result; } de_ctx->flags |= DE_QUIET; FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); SCClassConfLoadClassficationConfigFile(de_ctx, fd); de_ctx->sig_list = SigInit(de_ctx, "alert udp any any -> any any " "(msg:\"LogDropLog test\"; content:\"GET\"; Classtype:unknown; sid:1;)"); SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (p->alerts.cnt == 1 && p->alerts.alerts[0].action != ACTION_DROP) result = (strcmp(p->alerts.alerts[0].s->class_msg, "Unknown are we") == 0); if (LogDropCondition(NULL, p) == TRUE) LogDropLogger(NULL, &dlt, p); if (dlt.drop_cnt != 0) { printf("Packet shouldn't be logged but it is\n"); result = 0; } SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); UTHFreePackets(&p, 1); EngineModeSetIDS(); return result; }
/** * \test Check the ftpbounce match * \brief This test tests the ftpbounce condition match, based on * the ftp layer parser */ static int DetectFtpbounceTestALMatch03(void) { int result = 0; uint8_t ftpbuf1[] = { 'P','O' }; uint32_t ftplen1 = sizeof(ftpbuf1); uint8_t ftpbuf2[] = { 'R', 'T' }; uint32_t ftplen2 = sizeof(ftpbuf2); uint8_t ftpbuf3[] = { ' ', '1',',','2',',' }; uint32_t ftplen3 = sizeof(ftpbuf3); uint8_t ftpbuf4[] = "3,4,10,20\r\n"; uint32_t ftplen4 = sizeof(ftpbuf4); TcpSession ssn; Flow f; Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(p, 0, SIZE_OF_PACKET); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p->src.family = AF_INET; p->dst.family = AF_INET; p->src.addr_data32[0] = 0x04030201; p->payload = NULL; p->payload_len = 0; p->proto = IPPROTO_TCP; FLOW_INITIALIZE(&f); f.src.address.address_un_data32[0]=0x04030201; f.protoctx =(void *)&ssn; f.proto = IPPROTO_TCP; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_FTP; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any " "(msg:\"Ftp Bounce\"; ftpbounce; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v,(void *)de_ctx,(void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER, ftpbuf1, ftplen1); if (r != 0) { SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf2, ftplen2); if (r != 0) { SCLogDebug("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf3, ftplen3); if (r != 0) { SCLogDebug("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf4, ftplen4); if (r != 0) { SCLogDebug("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); FtpState *ftp_state = f.alstate; if (ftp_state == NULL) { SCLogDebug("no ftp state: "); result = 0; goto end; } if (ftp_state->command != FTP_COMMAND_PORT) { SCLogDebug("expected command port not detected"); result = 0; goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); /* It should not match */ if (!(PacketAlertCheck(p, 1))) { result = 1; } else { SCLogDebug("It should not match here!"); } end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v,(void *)det_ctx); DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); SCFree(p); return result; }
static int DetectThresholdTestSig1(void) { Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; int alerts = 0; HostInitConfig(HOST_QUIET); memset(&th_v, 0, sizeof(th_v)); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; content:\"A\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); if (s->flags & SIG_FLAG_IPONLY) { printf("signature is ip-only: "); goto end; } DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts = PacketAlertCheck(p, 1); if (alerts != 1) { printf("alerts %"PRIi32", expected 1: ", alerts); } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); if (alerts != 2) { printf("alerts %"PRIi32", expected 2: ", alerts); } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); if (alerts != 3) { printf("alerts %"PRIi32", expected 3: ", alerts); } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); if (alerts != 4) { printf("alerts %"PRIi32", expected 4: ", alerts); } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); if (alerts != 5) { printf("alerts %"PRIi32", expected 5: ", alerts); } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); if (alerts != 5) { printf("alerts %"PRIi32", expected 5: ", alerts); } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); if (alerts != 5) { printf("alerts %"PRIi32", expected 5: ", alerts); } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 1); if (alerts != 5) { printf("alerts %"PRIi32", expected 5: ", alerts); } if(alerts == 5) result = 1; else printf("alerts %"PRIi32", expected 5: ", alerts); SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); UTHFreePackets(&p, 1); HostShutdown(); end: return result; }
/** * \test DetectDsizeIcmpv6Test01 is a test for checking the working of * dsize keyword by creating 2 rules and matching a crafted packet * against them. Only the first one shall trigger. */ int DetectDsizeIcmpv6Test01 (void) { int result = 0; static uint8_t raw_icmpv6[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; IPV6Hdr ip6h; ThreadVars tv; DecodeThreadVars dtv; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; memset(&tv, 0, sizeof(ThreadVars)); memset(p, 0, SIZE_OF_PACKET); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&ip6h, 0, sizeof(IPV6Hdr)); memset(&th_v, 0, sizeof(ThreadVars)); FlowInitConfig(FLOW_QUIET); p->src.family = AF_INET6; p->dst.family = AF_INET6; p->ip6h = &ip6h; DecodeIPV6(&tv, &dtv, p, raw_icmpv6, sizeof(raw_icmpv6), NULL); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " "(msg:\"ICMP Large ICMP Packet\"; dsize:>8; sid:1; rev:4;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx, "alert icmp any any -> any any " "(msg:\"ICMP Large ICMP Packet\"; dsize:>800; sid:2; rev:4;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1) == 0) { printf("sid 1 did not alert, but should have: "); goto cleanup; } else if (PacketAlertCheck(p, 2)) { printf("sid 2 alerted, but should not have: "); goto cleanup; } result = 1; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); PACKET_RECYCLE(p); FlowShutdown(); end: SCFree(p); return result; }
static int DetectThresholdTestSig4(void) { Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; int alerts = 0; struct timeval ts; HostInitConfig(HOST_QUIET); memset (&ts, 0, sizeof(struct timeval)); TimeGet(&ts); memset(&th_v, 0, sizeof(th_v)); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type both, track by_dst, count 2, seconds 60; sid:10;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); TimeGet(&p->ts); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts = PacketAlertCheck(p, 10); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); TimeSetIncrementTime(200); TimeGet(&p->ts); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); if (alerts == 2) result = 1; else goto cleanup; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); end: UTHFreePackets(&p, 1); HostShutdown(); return result; }
/** * \test Test dce option. */ static int DetectBytetestTestParse20(void) { DetectEngineCtx *de_ctx = NULL; int result = 1; Signature *s = NULL; DetectBytetestData *bd = NULL; de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "dce_stub_data; " "content:\"one\"; distance:0; " "byte_test:1,=,1,6,relative,dce; sid:1;)"); if (de_ctx->sig_list == NULL) { result = 0; goto end; } s = de_ctx->sig_list; if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) { result = 0; goto end; } result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST); bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx; if (!(bd->flags & DETECT_BYTETEST_DCE) && !(bd->flags & DETECT_BYTETEST_RELATIVE) && (bd->flags & DETECT_BYTETEST_STRING) && (bd->flags & DETECT_BYTETEST_BIG) && (bd->flags & DETECT_BYTETEST_LITTLE) && (bd->flags & DETECT_BYTETEST_NEGOP) ) { result = 0; goto end; } s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "dce_stub_data; " "content:\"one\"; distance:0; " "byte_test:1,=,1,6,relative,dce; sid:1;)"); if (s->next == NULL) { result = 0; goto end; } s = s->next; if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) { result = 0; goto end; } result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST); bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx; if (!(bd->flags & DETECT_BYTETEST_DCE) && !(bd->flags & DETECT_BYTETEST_RELATIVE) && (bd->flags & DETECT_BYTETEST_STRING) && (bd->flags & DETECT_BYTETEST_BIG) && (bd->flags & DETECT_BYTETEST_LITTLE) && (bd->flags & DETECT_BYTETEST_NEGOP) ) { result = 0; goto end; } s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "dce_stub_data; " "content:\"one\"; distance:0; " "byte_test:1,=,1,6,relative; sid:1;)"); if (s->next == NULL) { result = 0; goto end; } s = s->next; if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) { result = 0; goto end; } result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST); bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx; if ((bd->flags & DETECT_BYTETEST_DCE) && !(bd->flags & DETECT_BYTETEST_RELATIVE) && (bd->flags & DETECT_BYTETEST_STRING) && (bd->flags & DETECT_BYTETEST_BIG) && (bd->flags & DETECT_BYTETEST_LITTLE) && (bd->flags & DETECT_BYTETEST_NEGOP) ) { result = 0; goto end; } end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; }
/** * \test Test drop action being set even if thresholded */ static int DetectThresholdTestSig7(void) { Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; int alerts = 0; int drops = 0; struct timeval ts; HostInitConfig(HOST_QUIET); memset (&ts, 0, sizeof(struct timeval)); TimeGet(&ts); memset(&th_v, 0, sizeof(th_v)); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 1, seconds 300; sid:10;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); TimeGet(&p->ts); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts = PacketAlertCheck(p, 10); drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); p->action = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); p->action = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); p->action = 0; TimeSetIncrementTime(200); TimeGet(&p->ts); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); p->action = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); p->action = 0; SigMatchSignatures(&th_v, de_ctx, det_ctx, p); alerts += PacketAlertCheck(p, 10); drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); p->action = 0; if (alerts == 1 && drops == 6) result = 1; else { if (alerts != 1) printf("alerts: %d != 1: ", alerts); if (drops != 6) printf("drops: %d != 6: ", drops); goto cleanup; } cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); end: UTHFreePackets(&p, 1); HostShutdown(); return result; }
/** * \test Test dce option. */ static int DetectBytetestTestParse21(void) { DetectEngineCtx *de_ctx = NULL; int result = 1; Signature *s = NULL; de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,string,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,big,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,little,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,hex,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,dec,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,oct,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,string,hex,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,big,string,hex,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,big,string,oct,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,little,string,hex,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } s = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing bytetest_body\"; " "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " "content:\"one\"; byte_test:1,=,1,6,big,string,dec,dce; sid:1;)"); if (s != NULL) { result = 0; goto end; } end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; }
static int DetectProtoTestSig01(void) { Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; Flow f; memset(&f, 0, sizeof(Flow)); memset(&th_v, 0, sizeof(th_v)); FLOW_INITIALIZE(&f); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flags |= PKT_HAS_FLOW; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert udp any any -> any any " "(msg:\"Not tcp\"; flow:to_server; sid:1;)"); if (s == NULL) goto end; s = s->next = SigInit(de_ctx,"alert ip any any -> any any " "(msg:\"IP\"; flow:to_server; sid:2;)"); if (s == NULL) goto end; s = s->next = SigInit(de_ctx,"alert tcp any any -> any any " "(msg:\"TCP\"; flow:to_server; sid:3;)"); if (s == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1)) { printf("sid 1 alerted, but should not have: "); goto cleanup; } else if (PacketAlertCheck(p, 2) == 0) { printf("sid 2 did not alert, but should have: "); goto cleanup; } else if (PacketAlertCheck(p, 3) == 0) { printf("sid 3 did not alert, but should have: "); goto cleanup; } result = 1; cleanup: FLOW_DESTROY(&f); SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); UTHFreePackets(&p, 1); end: return result; }
/** * \test DetectFragOffsetMatchTest01 is a test for checking the working of * fragoffset keyword by creating 2 rules and matching a crafted packet * against them. Only the first one shall trigger. */ int DetectFragOffsetMatchTest01 (void) { int result = 0; Packet *p = SCMalloc(SIZE_OF_PACKET); if (unlikely(p == NULL)) return 0; Signature *s = NULL; DecodeThreadVars dtv; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; IPV4Hdr ip4h; memset(p, 0, SIZE_OF_PACKET); p->pkt = (uint8_t *)(p + 1); memset(&ip4h, 0, sizeof(IPV4Hdr)); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&th_v, 0, sizeof(ThreadVars)); FlowInitConfig(FLOW_QUIET); p->src.family = AF_INET; p->dst.family = AF_INET; p->src.addr_data32[0] = 0x01020304; p->dst.addr_data32[0] = 0x04030201; ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; ip4h.ip_off = 0x2222; p->ip4h = &ip4h; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx, "alert ip any any -> any any (fragoffset:546; sid:1;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx, "alert ip any any -> any any (fragoffset:5000; sid:2;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1) == 0) { printf("sid 1 did not alert, but should have: "); goto cleanup; } else if (PacketAlertCheck(p, 2)) { printf("sid 2 alerted, but should not have: "); goto cleanup; } result = 1; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); FlowShutdown(); end: SCFree(p); return result; }
/** *\test Test that the negated http_header content matches against a * http request which doesn't hold the content. */ static int DetectHttpRawHeaderTest11(void) { TcpSession ssn; Packet *p = NULL; ThreadVars th_v; DetectEngineCtx *de_ctx = NULL; DetectEngineThreadCtx *det_ctx = NULL; HtpState *http_state = NULL; Flow f; uint8_t http_buf[] = "GET /index.html HTTP/1.0\r\n" "Host: www.openinfosecfoundation.org\r\n" "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" "Content-Type: text/html\r\n" "Content-Length: 26\r\n" "\r\n" "This is dummy message body\r\n"; uint32_t http_len = sizeof(http_buf) - 1; int result = 0; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.proto = IPPROTO_TCP; f.flags |= FLOW_IPV4; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_HTTP; StreamTcpInitConfig(TRUE); de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " "(msg:\"http header test\"; flow:to_server; " "content:!\"lalalalala\"; http_raw_header; " "sid:1;)"); if (de_ctx->sig_list == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); result = 0; SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); http_state = f.alstate; if (http_state == NULL) { printf("no http state: "); result = 0; goto end; } /* do detect */ SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { printf("sid 1 didn't match but should have: "); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (de_ctx != NULL) SigGroupCleanup(de_ctx); if (de_ctx != NULL) SigCleanSignatures(de_ctx); if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
/** * \test DetectICodeMatchTest01 is a test for checking the working of icode * keyword by creating 5 rules and matching a crafted packet against * them. 4 out of 5 rules shall trigger. */ int DetectICodeMatchTest01(void) { Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; int result = 0; memset(&th_v, 0, sizeof(th_v)); p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); p->icmpv4h->code = 10; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx,"alert icmp any any -> any any (icode:10; sid:1;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:<15; sid:2;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:>20; sid:3;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:8<>20; sid:4;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:20<>8; sid:5;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, 1) == 0) { SCLogDebug("sid 1 did not alert, but should have"); goto cleanup; } else if (PacketAlertCheck(p, 2) == 0) { SCLogDebug("sid 2 did not alert, but should have"); goto cleanup; } else if (PacketAlertCheck(p, 3)) { SCLogDebug("sid 3 alerted, but should not have"); goto cleanup; } else if (PacketAlertCheck(p, 4) == 0) { SCLogDebug("sid 4 did not alert, but should have"); goto cleanup; } else if (PacketAlertCheck(p, 5) == 0) { SCLogDebug("sid 5 did not alert, but should have"); goto cleanup; } result = 1; cleanup: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); UTHFreePackets(&p, 1); end: return result; }
static int XBitsTestSig02(void) { Signature *s = NULL; ThreadVars th_v; DetectEngineCtx *de_ctx = NULL; int result = 0; int error_count = 0; memset(&th_v, 0, sizeof(th_v)); de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (xbits:isset,abc,track ip_src; content:\"GET \"; sid:1;)"); if (s == NULL) { error_count++; } s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (xbits:isnotset,abc,track ip_dst; content:\"GET \"; sid:2;)"); if (s == NULL) { error_count++; } s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (xbits:set,abc,track ip_pair; content:\"GET \"; sid:3;)"); if (s == NULL) { error_count++; } s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (xbits:unset,abc,track ip_src; content:\"GET \"; sid:4;)"); if (s == NULL) { error_count++; } s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (xbits:toggle,abc,track ip_dst; content:\"GET \"; sid:5;)"); if (s == NULL) { error_count++; } if (error_count != 0) goto end; result = 1; SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; end: if (de_ctx != NULL) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); } return result; }
/** \test Check a signature with gievn urilen */ static int DetectUrilenSigTest01(void) { int result = 0; Flow f; uint8_t httpbuf1[] = "POST /suricata HTTP/1.0\r\n" "Host: foo.bar.tld\r\n" "\r\n"; uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ TcpSession ssn; Packet *p = NULL; Signature *s = NULL; ThreadVars th_v; DetectEngineThreadCtx *det_ctx; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&th_v, 0, sizeof(th_v)); memset(&f, 0, sizeof(f)); memset(&ssn, 0, sizeof(ssn)); p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.proto = IPPROTO_TCP; f.flags |= FLOW_IPV4; p->flow = &f; p->flowflags |= FLOW_PKT_TOSERVER; p->flowflags |= FLOW_PKT_ESTABLISHED; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; f.alproto = ALPROTO_HTTP; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing urilen\"; " "urilen: <5; sid:1;)"); if (s == NULL) { goto end; } s = s->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"Testing http_method\"; " "urilen: >5; sid:2;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); FLOWLOCK_WRLOCK(&f); int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); if (r != 0) { SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); FLOWLOCK_UNLOCK(&f); goto end; } FLOWLOCK_UNLOCK(&f); HtpState *htp_state = f.alstate; if (htp_state == NULL) { SCLogDebug("no http state: "); goto end; } SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if ((PacketAlertCheck(p, 1))) { printf("sid 1 alerted, but should not have: \n"); goto end; } if (!PacketAlertCheck(p, 2)) { printf("sid 2 did not alerted, but should have: \n"); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (de_ctx != NULL) SigGroupCleanup(de_ctx); if (de_ctx != NULL) SigCleanSignatures(de_ctx); if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePackets(&p, 1); return result; }
/** \test simple google.com query matching (TCP) */ static int DetectDnsQueryTest03(void) { /* google.com */ uint8_t buf[] = { 0x00, 28, 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x10, 0x00, 0x01, }; int result = 0; Flow f; DNSState *dns_state = NULL; Packet *p = NULL; Signature *s = NULL; ThreadVars tv; DetectEngineThreadCtx *det_ctx = NULL; TcpSession ssn; AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); memset(&tv, 0, sizeof(ThreadVars)); memset(&f, 0, sizeof(Flow)); memset(&ssn, 0, sizeof(TcpSession)); p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP, "192.168.1.5", "192.168.1.1", 41424, 53); FLOW_INITIALIZE(&f); f.protoctx = (void *)&ssn; f.flags |= FLOW_IPV4; f.proto = IPPROTO_TCP; f.protomap = FlowGetProtoMapping(f.proto); p->flow = &f; p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; p->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED; f.alproto = ALPROTO_DNS; StreamTcpInitConfig(TRUE); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->mpm_matcher = DEFAULT_MPM; de_ctx->flags |= DE_QUIET; s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " "(msg:\"Test dns_query option\"; " "content:\"google\"; nocase; dns_query; sid:1;)"); if (s == NULL) { goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); SCMutexLock(&f.m); int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf, sizeof(buf)); if (r != 0) { printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); SCMutexUnlock(&f.m); goto end; } SCMutexUnlock(&f.m); dns_state = f.alstate; if (dns_state == NULL) { printf("no dns state: "); goto end; } /* do detect */ SigMatchSignatures(&tv, de_ctx, det_ctx, p); if (!(PacketAlertCheck(p, 1))) { printf("sig 1 didn't alert, but it should have: "); goto end; } result = 1; end: if (alp_tctx != NULL) AppLayerParserThreadCtxFree(alp_tctx); if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&tv, det_ctx); if (de_ctx != NULL) SigGroupCleanup(de_ctx); if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); StreamTcpFreeConfig(TRUE); FLOW_DESTROY(&f); UTHFreePacket(p); return result; }
/** * \test Test packet Matches * \param raw_eth_pkt pointer to the ethernet packet * \param pktsize size of the packet * \param sig pointer to the signature to test * \param sid sid number of the signature * \retval return 1 if match * \retval return 0 if not */ int DetectReplaceLongPatternMatchTest(uint8_t *raw_eth_pkt, uint16_t pktsize, char *sig, uint32_t sid, uint8_t *pp, uint16_t *len) { int result = 0; Packet *p = NULL; p = PacketGetFromAlloc(); if (unlikely(p == NULL)) return 0; DecodeThreadVars dtv; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; if (pp == NULL) { SCLogDebug("replace: looks like a second run"); } PacketCopyData(p, raw_eth_pkt, pktsize); memset(&dtv, 0, sizeof(DecodeThreadVars)); memset(&th_v, 0, sizeof(th_v)); dtv.app_tctx = AppLayerGetCtxThread(&th_v); FlowInitConfig(FLOW_QUIET); DecodeEthernet(&th_v, &dtv, p, GET_PKT_DATA(p), pktsize, NULL); DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { goto end; } de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, sig); if (de_ctx->sig_list == NULL) { goto end; } de_ctx->sig_list->next = NULL; if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->type == DETECT_CONTENT) { DetectContentData *co = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; if (co->flags & DETECT_CONTENT_RELATIVE_NEXT) { printf("relative next flag set on final match which is content: "); goto end; } } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, p); if (PacketAlertCheck(p, sid) != 1) { SCLogDebug("replace: no alert on sig %d", sid); goto end; } if (pp) { memcpy(pp, GET_PKT_DATA(p), GET_PKT_LEN(p)); *len = pktsize; SCLogDebug("replace: copying %d on %p", *len, pp); } result = 1; end: if (dtv.app_tctx != NULL) AppLayerDestroyCtxThread(dtv.app_tctx); if (de_ctx != NULL) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); } PACKET_RECYCLE(p); FlowShutdown(); SCFree(p); return result; }