190static void AppLayerProtoDetectPEGetIpprotos(
AppProto alproto,
201 uint32_t buflen, uint16_t searchlen,
bool *rflow)
206 SCLogDebug(
"s->co->offset (%"PRIu16
") > searchlen (%"PRIu16
")",
210 if (s->
cd->
depth > searchlen) {
211 SCLogDebug(
"s->co->depth (%"PRIu16
") > searchlen (%"PRIu16
")",
216 const uint8_t *sbuf = buf + s->
cd->
offset;
218 SCLogDebug(
"s->co->offset (%"PRIu16
") s->cd->depth (%"PRIu16
")",
227 uint8_t direction = (
flags & (STREAM_TOSERVER | STREAM_TOCLIENT));
228 SCLogDebug(
"matching, s->direction %s, our dir %s",
229 (s->
direction & STREAM_TOSERVER) ?
"toserver" :
"toclient",
230 (
flags & STREAM_TOSERVER) ?
"toserver" :
"toclient");
235 SCLogDebug(
"direction is wrong, rflow = true");
241 SCLogDebug(
"PP can't be run yet as pp_min_depth %u > buflen %u",
249 SCLogDebug(
"found %s/%u, rdir %02x reverse_flow? %s",
251 (rdir && direction != rdir) ?
"true" :
"false");
252 *rflow = (rdir && direction != rdir);
259 SCLogDebug(
"depth reached and answer inconclusive: fail");
274 uint32_t buflen, uint8_t
flags,
AppProto *pm_results,
bool *rflow)
280 SCLogDebug(
"searchlen %u buflen %u", searchlen, buflen);
286 if (search_cnt == 0) {
294 memset(pm_results_bf, 0,
sizeof(pm_results_bf));
303 s, tctx, f,
flags, buf, buflen, searchlen, rflow);
306 if (AppProtoIsValid(
proto) &&
307 !(pm_results_bf[
proto / 8] & (1 << (
proto % 8))) )
309 pm_results[pm_matches++] =
proto;
315 if (pm_matches == 0 && buflen >= pm_ctx->
pp_max_len) {
327 const uint8_t *buf, uint32_t buflen, uint8_t
flags,
AppProto *pm_results,
bool *rflow)
342 if (
flags & STREAM_TOSERVER) {
350 m = PMGetProtoInspect(tctx, pm_ctx, mpm_tctx, f, buf, buflen,
flags, pm_results, rflow);
371 if (
flags & STREAM_TOSERVER) {
378 SCLogDebug(
"no matches and in midstream mode, lets try the "
379 "*patterns for the other side");
383 om = PMGetProtoInspect(
384 tctx, pm_ctx, mpm_tctx, f, buf, buflen,
flags, pm_results, rflow);
392 }
else if (om < 0 &&
m &&
m < 0) {
397 }
else if (om == 0 ||
m == 0) {
419 while (pp_port != NULL) {
420 if (pp_port->
dp != NULL && pp_port->
dp->
alproto == alproto) {
421 pp_elem = pp_port->
dp;
424 if (pp_port->
sp != NULL && pp_port->
sp->
alproto == alproto) {
425 pp_elem = pp_port->
sp;
428 pp_port = pp_port->
next;
431 SCReturnPtr(pp_elem,
"AppLayerProtoDetectProbingParserElement *");
451 while (pp_port != NULL) {
456 pp_port = pp_port->
next;
460 SCReturnPtr(pp_port,
"AppLayerProtoDetectProbingParserPort *");
481 uint8_t
flags,
const uint8_t *buf, uint32_t buflen, uint32_t *alproto_masks, uint8_t *rdir,
486 if (alproto_masks != NULL) {
488 if (buflen < pe->min_depth || (alproto_masks[0] &
BIT_U32(*nb_tried))) {
491 *nb_tried = *nb_tried + 1;
494 }
else if (buflen < pe->min_depth) {
505 if (AppProtoIsValid(alproto)) {
508 if (alproto_masks != NULL) {
511 alproto_masks[0] |=
BIT_U32(*nb_tried);
513 *nb_tried = *nb_tried + 1;
528static AppProto AppLayerProtoDetectPPGetProto(
Flow *f,
const uint8_t *buf, uint32_t buflen,
529 uint8_t ipproto,
const uint8_t
flags,
bool *reverse_flow)
549 uint8_t nb_tried = 0;
550 uint32_t *alproto_masks = NULL;
551 uint8_t idir = (
flags & (STREAM_TOSERVER | STREAM_TOCLIENT));
555 bool probe_is_found =
false;
562 (dir == STREAM_TOSERVER) ?
"toserver" :
"toclient");
564 if (dir == STREAM_TOSERVER) {
566 pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.
ctx_pp, ipproto, dp);
568 if (pp_port_dp != NULL) {
569 SCLogDebug(
"toserver - Probing parser found for destination port %"PRIu16, dp);
572 pe1 = pp_port_dp->
dp;
574 SCLogDebug(
"toserver - No probing parser registered for dest port %"PRIu16, dp);
577 pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.
ctx_pp, ipproto, sp);
578 if (pp_port_sp != NULL) {
579 SCLogDebug(
"toserver - Probing parser found for source port %"PRIu16, sp);
582 pe2 = pp_port_sp->
sp;
584 SCLogDebug(
"toserver - No probing parser registered for source port %"PRIu16, sp);
588 pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.
ctx_pp, ipproto, dp);
594 if (pp_port_dp != NULL) {
595 SCLogDebug(
"toclient - Probing parser found for destination port %"PRIu16, dp);
598 pe1 = pp_port_dp->
dp;
600 SCLogDebug(
"toclient - No probing parser registered for dest port %"PRIu16, dp);
603 pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.
ctx_pp, ipproto, sp);
604 if (pp_port_sp != NULL) {
605 SCLogDebug(
"toclient - Probing parser found for source port %"PRIu16, sp);
607 pe2 = pp_port_sp->
sp;
609 SCLogDebug(
"toclient - No probing parser registered for source port %"PRIu16, sp);
617 pe0 = AppLayerProtoDetectGetProbingParser(alpd_ctx.
ctx_pp, ipproto, f->
alproto_tc);
619 pe0 = AppLayerProtoDetectGetProbingParser(alpd_ctx.
ctx_pp, ipproto, f->
alproto_ts);
622 if (pe1 == NULL && pe2 == NULL && pe0 == NULL) {
623 SCLogDebug(
"%s - No probing parsers found for either port",
624 (dir == STREAM_TOSERVER) ?
"toserver":
"toclient");
627 probe_is_found =
true;
633 alproto = PPGetProto(pe0, f,
flags, buf, buflen, NULL, &rdir, NULL);
634 if (AppProtoIsValid(alproto))
636 alproto = PPGetProto(pe1, f,
flags, buf, buflen, alproto_masks, &rdir, &nb_tried);
637 if (AppProtoIsValid(alproto))
639 alproto = PPGetProto(pe2, f,
flags, buf, buflen, alproto_masks, &rdir, &nb_tried);
640 if (AppProtoIsValid(alproto))
647 if (alproto_masks[0] ==
BIT_U32(nb_tried) - 1) {
649 SCLogDebug(
"%s, mask is now %08x, needed %08x, so done",
650 (dir == STREAM_TOSERVER) ?
"toserver" :
"toclient", alproto_masks[0],
654 (dir == STREAM_TOSERVER) ?
"toserver" :
"toclient", alproto_masks[0],
661 if (idir == STREAM_TOSERVER) {
662 dir = STREAM_TOCLIENT;
664 dir = STREAM_TOSERVER;
666 SCLogDebug(
"no match + midstream, retry the other direction %s",
667 (dir == STREAM_TOSERVER) ?
"toserver" :
"toclient");
668 goto again_midstream;
669 }
else if (!probe_is_found) {
674 if (AppProtoIsValid(alproto) && rdir != 0 && rdir != idir) {
675 SCLogDebug(
"PP found %u, is reverse flow", alproto);
676 *reverse_flow =
true;
680 (idir == STREAM_TOSERVER) ?
"toserver":
"toclient", alproto_masks[0]);
686static void AppLayerProtoDetectPPGetIpprotos(
AppProto alproto,
695 for (pp = alpd_ctx.
ctx_pp; pp != NULL; pp = pp->
next) {
696 for (pp_port = pp->
port; pp_port != NULL; pp_port = pp_port->
next) {
697 for (pp_pe = pp_port->
dp; pp_pe != NULL; pp_pe = pp_pe->
next) {
701 for (pp_pe = pp_port->
sp; pp_pe != NULL; pp_pe = pp_pe->
next) {
721 SCReturnPtr(p,
"AppLayerProtoDetectProbingParserElement");
742 SCReturnPtr(p,
"AppLayerProtoDetectProbingParserPort");
754 AppLayerProtoDetectProbingParserElementFree(e);
761 AppLayerProtoDetectProbingParserElementFree(e);
779 SCReturnPtr(p,
"AppLayerProtoDetectProbingParser");
789 AppLayerProtoDetectProbingParserPortFree(pt);
799 AppProto alproto, uint16_t min_depth, uint16_t max_depth)
808 if (max_depth != 0 && min_depth >= max_depth) {
810 "register the probing parser. min_depth >= max_depth");
813 if (alproto <= ALPROTO_UNKNOWN || alproto >=
g_alproto_max) {
814 SCLogError(
"Invalid arguments sent to register "
815 "the probing parser. Invalid alproto - %d",
820 SCReturnPtr(pe,
"AppLayerProtoDetectProbingParserElement");
822 AppLayerProtoDetectProbingParserElementFree(pe);
823 SCReturnPtr(NULL,
"AppLayerProtoDetectProbingParserElement");
840 SCReturnPtr(new_pe,
"AppLayerProtoDetectProbingParserElement");
851 printf(
"\nProtocol Detection Configuration\n");
853 for ( ; pp != NULL; pp = pp->
next) {
855 if (pp->
ipproto == IPPROTO_TCP)
856 printf(
"IPProto: TCP\n");
857 else if (pp->
ipproto == IPPROTO_UDP)
858 printf(
"IPProto: UDP\n");
860 printf(
"IPProto: %"PRIu8
"\n", pp->
ipproto);
863 for ( ; pp_port != NULL; pp_port = pp_port->
next) {
864 if (pp_port->
dp != NULL) {
865 printf(
" Port: %"PRIu16
"\n", pp_port->
port);
867 printf(
" Destination port: (max-depth: %" PRIu16
")\n",
870 for ( ; pp_pe != NULL; pp_pe = pp_pe->
next) {
873 printf(
" min_depth: %"PRIu32
"\n", pp_pe->
min_depth);
874 printf(
" max_depth: %"PRIu32
"\n", pp_pe->
max_depth);
880 if (pp_port->
sp == NULL) {
884 printf(
" Source port: (max-depth: %" PRIu16
")\n", pp_port->
sp_max_depth);
886 for ( ; pp_pe != NULL; pp_pe = pp_pe->
next) {
889 printf(
" min_depth: %"PRIu32
"\n", pp_pe->
min_depth);
890 printf(
" max_depth: %"PRIu32
"\n", pp_pe->
max_depth);
906 if (*head_pe == NULL) {
912 while (temp_pe->
next != NULL)
913 temp_pe = temp_pe->
next;
914 temp_pe->
next = new_pe;
924 if (*head_pp == NULL) {
930 while (temp_pp->
next != NULL)
931 temp_pp = temp_pp->
next;
932 temp_pp->
next = new_pp;
943 if (*head_port == NULL) {
944 *head_port = new_port;
949 if ((*head_port)->port == 0 && (*head_port)->use_ports) {
950 new_port->
next = *head_port;
951 *head_port = new_port;
954 while (temp_port->
next != NULL &&
956 temp_port = temp_port->
next;
959 temp_port->
next = new_port;
967 uint8_t ipproto,
bool use_ports, uint16_t port,
AppProto alproto, uint16_t min_depth,
975 while (curr_pp != NULL) {
976 if (curr_pp->
ipproto == ipproto)
978 curr_pp = curr_pp->
next;
980 if (curr_pp == NULL) {
983 AppLayerProtoDetectProbingParserAppend(pp, new_pp);
989 while (curr_port != NULL) {
991 if (curr_port->
port == port && use_ports)
993 curr_port = curr_port->
next;
995 if (curr_port == NULL) {
997 new_port->
port = port;
999 AppLayerProtoDetectProbingParserPortAppend(&curr_pp->
port, new_port);
1000 curr_port = new_port;
1001 if (direction & STREAM_TOSERVER) {
1009 zero_port = curr_pp->
port;
1011 while (zero_port != NULL && !(zero_port->
port == 0 && zero_port->
use_ports)) {
1012 zero_port = zero_port->
next;
1014 if (zero_port != NULL) {
1017 zero_pe = zero_port->
dp;
1018 for ( ; zero_pe != NULL; zero_pe = zero_pe->
next) {
1019 if (curr_port->
dp == NULL)
1029 AppLayerProtoDetectProbingParserElementDuplicate(zero_pe);
1030 AppLayerProtoDetectProbingParserElementAppend(&curr_port->
dp, dup_pe);
1033 zero_pe = zero_port->
sp;
1034 for ( ; zero_pe != NULL; zero_pe = zero_pe->
next) {
1035 if (curr_port->
sp == NULL)
1045 AppLayerProtoDetectProbingParserElementDuplicate(zero_pe);
1046 AppLayerProtoDetectProbingParserElementAppend(&curr_port->
sp, dup_pe);
1053 if (direction & STREAM_TOSERVER)
1054 curr_pe = curr_port->
dp;
1056 curr_pe = curr_port->
sp;
1057 while (curr_pe != NULL) {
1058 if (curr_pe->
alproto == alproto) {
1060 "ipproto - %" PRIu8
" Port - %" PRIu16
" "
1061 "App Protocol - NULL, App Protocol(ID) - "
1062 "%" PRIu16
" min_depth - %" PRIu16
" "
1063 "max_dept - %" PRIu16
".",
1064 ipproto, port, alproto, min_depth, max_depth);
1067 curr_pe = curr_pe->
next;
1071 AppLayerProtoDetectProbingParserElementCreate(alproto, min_depth, max_depth);
1076 if (direction & STREAM_TOSERVER) {
1079 if (curr_port->
dp == NULL)
1087 head_pe = &curr_port->
dp;
1091 if (curr_port->
sp == NULL)
1099 head_pe = &curr_port->
sp;
1101 AppLayerProtoDetectProbingParserElementAppend(head_pe, new_pe);
1106 while (temp_port != NULL && !(temp_port->
port == 0 && temp_port->
use_ports)) {
1107 if (direction & STREAM_TOSERVER) {
1108 if (temp_port->
dp == NULL)
1116 AppLayerProtoDetectProbingParserElementAppend(
1117 &temp_port->
dp, AppLayerProtoDetectProbingParserElementDuplicate(curr_pe));
1119 if (temp_port->
sp == NULL)
1127 AppLayerProtoDetectProbingParserElementAppend(
1128 &temp_port->
sp, AppLayerProtoDetectProbingParserElementDuplicate(curr_pe));
1130 temp_port = temp_port->
next;
1140static void AppLayerProtoDetectPMGetIpprotos(
AppProto alproto,
1147 for (
int j = 0; j < 2; j++) {
1153 ipprotos[ipproto / 8] |= 1 << (ipproto % 8);
1165 typedef struct TempContainer_ {
1167 uint16_t content_len;
1172 uint32_t struct_total_size = 0;
1173 uint32_t content_total_size = 0;
1175 uint8_t *ahb = NULL;
1176 uint8_t *content = NULL;
1177 uint16_t content_len = 0;
1179 TempContainer *struct_offset = NULL;
1180 uint8_t *content_offset = NULL;
1183 if (
ctx->head == NULL)
1186 for (s =
ctx->head; s != NULL; s = s->
next) {
1187 struct_total_size +=
sizeof(TempContainer);
1192 ahb =
SCMalloc(
sizeof(uint8_t) * (struct_total_size + content_total_size));
1196 struct_offset = (TempContainer *)ahb;
1197 content_offset = ahb + struct_total_size;
1198 for (s =
ctx->head; s != NULL; s = s->
next) {
1199 TempContainer *tcdup = (TempContainer *)ahb;
1203 for (; tcdup != struct_offset; tcdup++) {
1204 if (tcdup->content_len != content_len ||
1205 SCMemcmp(tcdup->content, content, tcdup->content_len) != 0)
1212 if (tcdup != struct_offset) {
1213 s->
cd->
id = tcdup->id;
1217 struct_offset->content_len = content_len;
1218 struct_offset->content = content_offset;
1219 content_offset += content_len;
1220 memcpy(struct_offset->content, content, content_len);
1221 struct_offset->id = max_id++;
1222 s->
cd->
id = struct_offset->id;
1227 ctx->max_pat_id = max_id;
1248 if (
ctx->map == NULL)
1252 for (s =
ctx->head; s != NULL; ) {
1272 ctx->map[s->
id] = s;
1314 AppProto alproto, uint8_t direction,
1316 uint16_t pp_min_depth, uint16_t pp_max_depth)
1338static int AppLayerProtoDetectPMRegisterPattern(uint8_t ipproto,
AppProto alproto,
1339 const char *pattern,
1340 uint16_t depth, uint16_t
offset,
1344 uint16_t pp_min_depth, uint16_t pp_max_depth)
1368 if (depth < cd->content_len)
1371 if (direction & STREAM_TOSERVER)
1378 if (depth < ctx_pm->min_len)
1382 AppLayerProtoDetectPMAddSignature(ctx_pm, cd, alproto, direction,
1383 PPFunc, pp_min_depth, pp_max_depth);
1396 const uint8_t *buf, uint32_t buflen, uint8_t ipproto, uint8_t
flags,
bool *reverse_flow)
1399 SCLogDebug(
"buflen %u for %s direction", buflen,
1400 (
flags & STREAM_TOSERVER) ?
"toserver" :
"toclient");
1406 uint16_t pm_matches = AppLayerProtoDetectPMGetProto(
1407 tctx, f, buf, buflen,
flags, pm_results, reverse_flow);
1408 if (pm_matches > 0) {
1410 alproto = pm_results[0];
1413 uint8_t reverse_dir = (
flags & STREAM_TOSERVER) ? STREAM_TOCLIENT : STREAM_TOSERVER;
1426 alproto = AppLayerProtoDetectPPGetProto(f, buf, buflen, ipproto,
flags, reverse_flow);
1427 if (AppProtoIsValid(alproto)) {
1435 alproto = AppLayerProtoDetectPEGetProto(f,
flags);
1450 while (pp != NULL) {
1452 AppLayerProtoDetectProbingParserFree(pp);
1460static void AppLayerProtoDetectFreeAliases(
void)
1465 if (cur_alias == NULL)
1469 while (cur_alias != NULL) {
1470 next_alias = cur_alias->
next;
1472 cur_alias = next_alias;
1492 for (j = 0; j < 2; j++) {
1495 if (AppLayerProtoDetectPMSetContentIDs(ctx_pm) < 0)
1501 if (AppLayerProtoDetectPMMapSignatures(ctx_pm) < 0)
1503 if (AppLayerProtoDetectPMPrepareMpm(ctx_pm) < 0)
1510 AppLayerProtoDetectPrintProbingParsers(alpd_ctx.
ctx_pp);
1528 uint16_t min_depth, uint16_t max_depth, uint8_t direction,
ProbingParserFPtr ProbingParser1,
1534 if (portstr == NULL) {
1537 AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.
ctx_pp, ipproto,
false, 0, alproto,
1538 min_depth, max_depth, direction, ProbingParser1, ProbingParser2);
1543 while (temp_dp != NULL) {
1544 uint16_t port = temp_dp->
port;
1545 if (port == 0 && temp_dp->
port2 != 0)
1548 AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.
ctx_pp, ipproto,
true, port,
1549 alproto, min_depth, max_depth, direction, ProbingParser1, ProbingParser2);
1550 if (port == temp_dp->
port2) {
1556 temp_dp = temp_dp->
next;
1564 const char *alproto_name,
AppProto alproto, uint16_t min_depth, uint16_t max_depth,
1575 r = snprintf(param,
sizeof(param),
"%s%s%s",
"app-layer.protocols.",
1576 alproto_name,
".detection-ports");
1579 }
else if (r > (
int)
sizeof(param)) {
1580 FatalError(
"buffer not big enough to write param.");
1584 SCLogDebug(
"Entry for %s not found.", param);
1585 r = snprintf(param,
sizeof(param),
"%s%s%s%s%s",
"app-layer.protocols.",
1586 alproto_name,
".", ipproto_name,
".detection-ports");
1589 }
else if (r > (
int)
sizeof(param)) {
1590 FatalError(
"buffer not big enough to write param.");
1599 if (port_node == NULL)
1602 if (port_node != NULL && port_node->
val != NULL) {
1605 ProbingParserTs, ProbingParserTc);
1610 if (port_node == NULL)
1613 if (port_node != NULL && port_node->
val != NULL) {
1616 ProbingParserTc, ProbingParserTs);
1627 uint16_t depth, uint16_t
offset, uint8_t direction)
1630 int r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto,
1638 const char *pattern, uint16_t depth, uint16_t
offset, uint8_t direction,
1642 int r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto,
1645 PPFunc, pp_min_depth, pp_max_depth);
1650 uint16_t depth, uint16_t
offset, uint8_t direction)
1653 int r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto,
1668 memset(&alpd_ctx, 0,
sizeof(alpd_ctx));
1675 FatalError(
"Unable to alloc SpmGlobalThreadCtx.");
1679 for (j = 0; j < 2; j++) {
1686 FatalError(
"Unable to alloc alproto_names.");
1692 FatalError(
"Unable to alloc expectation_proto.");
1707 int ipproto_map = 0;
1714 for (dir = 0; dir < 2; dir++) {
1717 for (
id = 0;
id < pm_ctx->
max_sig_id;
id++) {
1718 sig = pm_ctx->
map[
id];
1719 AppLayerProtoDetectPMFreeSignature(sig);
1735 AppLayerProtoDetectFreeAliases();
1737 AppLayerProtoDetectFreeProbingParsers(alpd_ctx.
ctx_pp);
1749 FatalError(
"Unable to realloc alproto_names.");
1773 new_alias->
next = NULL;
1775 if (alpda_ctx == NULL) {
1776 alpda_ctx = new_alias;
1779 while (cur_alias->
next != NULL) {
1780 cur_alias = cur_alias->
next;
1782 cur_alias->
next = new_alias;
1846 if (new_proto != f->
alproto) {
1873 const char *ipproto,
const char *alproto,
bool default_enabled)
1877 BUG_ON(ipproto == NULL || alproto == NULL);
1887#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1889 default_enabled =
true;
1892 r = snprintf(param,
sizeof(param),
"%s%s%s",
"app-layer.protocols.",
1893 alproto,
".enabled");
1896 }
else if (r > (
int)
sizeof(param)) {
1897 FatalError(
"buffer not big enough to write param.");
1902 SCLogDebug(
"Entry for %s not found.", param);
1903 r = snprintf(param,
sizeof(param),
"%s%s%s%s%s",
"app-layer.protocols.",
1904 alproto,
".", ipproto,
".enabled");
1907 }
else if (r > (
int)
sizeof(param)) {
1908 FatalError(
"buffer not big enough to write param.");
1913 SCLogDebug(
"Entry for %s not found.", param);
1914 if (default_enabled) {
1927 }
else if (strcasecmp(node->
val,
"detection-only") == 0) {
1933 SCLogError(
"Invalid value found for %s.", param);
1958 for (j = 0; j < 2; j++) {
1959 if (max_pat_id == 0) {
1979 for (j = 0; j < 2; j++) {
2006 int ipproto_map, dir;
2009 for (dir = 0; dir < 2; dir++) {
2038 AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos);
2039 AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos);
2040 AppLayerProtoDetectPEGetIpprotos(alproto, ipprotos);
2051 while (cur_alias != NULL) {
2052 if (strcasecmp(alproto_name, cur_alias->
proto_alias) == 0) {
2056 cur_alias = cur_alias->
next;
2062 if (alpd_ctx.
alproto_names[a] != NULL && AppProtoEquals(b, a)) {
2098 alprotos[alproto] = 1;
2104static void AppLayerProtoDetectPEGetIpprotos(
AppProto alproto,
2111 ipprotos[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);
2114 ipprotos[IPPROTO_UDP / 8] |= 1 << (IPPROTO_UDP % 8);
2122 SCLogError(
"Expectation on 2 IP protocols are not supported");
2140 alpd_ctx_ut = alpd_ctx;
2141 memset(&alpd_ctx, 0,
sizeof(alpd_ctx));
2148 alpd_ctx = alpd_ctx_ut;
2149 memset(&alpd_ctx_ut, 0,
sizeof(alpd_ctx_ut));
2153static int AppLayerProtoDetectTest01(
void)
2158 const char *buf =
"HTTP";
2174static int AppLayerProtoDetectTest02(
void)
2179 const char *buf =
"HTTP";
2200static int AppLayerProtoDetectTest03(
void)
2205 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n";
2207 memset(pm_results, 0,
sizeof(pm_results));
2209 memset(&f, 0x00,
sizeof(f));
2213 const char *buf =
"HTTP";
2233 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2234 &f, l7data,
sizeof(l7data),
2236 pm_results, &rflow);
2246static int AppLayerProtoDetectTest04(
void)
2251 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n";
2253 memset(&f, 0x00,
sizeof(f));
2255 memset(pm_results, 0,
sizeof(pm_results));
2258 const char *buf =
"200 ";
2275 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2276 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2287static int AppLayerProtoDetectTest05(
void)
2292 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n<HTML><BODY>Blahblah</BODY></HTML>";
2294 memset(pm_results, 0,
sizeof(pm_results));
2296 memset(&f, 0x00,
sizeof(f));
2299 const char *buf =
"HTTP";
2319 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2320 &f, l7data,
sizeof(l7data),
2332static int AppLayerProtoDetectTest06(
void)
2337 uint8_t l7data[] =
"220 Welcome to the OISF FTP server\r\n";
2339 memset(pm_results, 0,
sizeof(pm_results));
2341 memset(&f, 0x00,
sizeof(f));
2344 const char *buf =
"HTTP";
2364 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2365 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2376static int AppLayerProtoDetectTest07(
void)
2381 uint8_t l7data[] =
"220 Welcome to the OISF HTTP/FTP server\r\n";
2383 memset(&f, 0x00,
sizeof(f));
2386 memset(pm_results, 0,
sizeof(pm_results));
2388 const char *buf =
"HTTP";
2404 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2405 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2415static int AppLayerProtoDetectTest08(
void)
2420 uint8_t l7data[] = {
2421 0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, 0x42,
2422 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8,
2423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe,
2425 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02,
2426 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f,
2427 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52,
2428 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02,
2429 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e,
2430 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f,
2431 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57,
2432 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70,
2433 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 0x02,
2434 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30,
2435 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41,
2436 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54,
2437 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32,
2441 memset(pm_results, 0,
sizeof(pm_results));
2443 memset(&f, 0x00,
sizeof(f));
2446 const char *buf =
"|ff|SMB";
2462 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2463 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2474static int AppLayerProtoDetectTest09(
void)
2479 uint8_t l7data[] = {
2480 0x00, 0x00, 0x00, 0x66, 0xfe, 0x53, 0x4d, 0x42,
2481 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2482 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
2483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2488 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x00,
2489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2496 memset(pm_results, 0,
sizeof(pm_results));
2498 memset(&f, 0x00,
sizeof(f));
2501 const char *buf =
"|fe|SMB";
2517 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2518 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2529static int AppLayerProtoDetectTest10(
void)
2534 uint8_t l7data[] = {
2535 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
2536 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2537 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00,
2538 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
2539 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11,
2540 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57,
2541 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
2542 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
2543 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00
2546 memset(pm_results, 0,
sizeof(pm_results));
2548 memset(&f, 0x00,
sizeof(f));
2551 const char *buf =
"|05 00|";
2568 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2569 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2584static int AppLayerProtoDetectTest11(
void)
2589 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2590 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2592 memset(pm_results, 0,
sizeof(pm_results));
2594 memset(&f, 0x00,
sizeof(f));
2606 IPPROTO_TCP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2608 IPPROTO_TCP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2610 IPPROTO_TCP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2635 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2636 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2641 memset(pm_results, 0,
sizeof(pm_results));
2643 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2657static int AppLayerProtoDetectTest12(
void)
2669 printf(
"failure 1\n");
2675 printf(
"failure 2\n");
2681 printf(
"failure 3\n");
2685 printf(
"failure 4\n");
2689 printf(
"failure 5\n");
2693 printf(
"failure 6\n");
2709static int AppLayerProtoDetectTest13(
void)
2714 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2715 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2719 memset(&f, 0x00,
sizeof(f));
2731 IPPROTO_UDP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2733 IPPROTO_UDP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2735 IPPROTO_UDP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2756 memset(pm_results, 0,
sizeof(pm_results));
2758 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2759 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2763 memset(pm_results, 0,
sizeof(pm_results));
2765 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2780static int AppLayerProtoDetectTest14(
void)
2785 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2786 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2790 memset(&f, 0x00,
sizeof(f));
2802 IPPROTO_UDP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2804 IPPROTO_UDP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2806 IPPROTO_UDP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2828 memset(pm_results, 0,
sizeof(pm_results));
2831 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2836 memset(pm_results, 0,
sizeof(pm_results));
2838 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2881 int i = -1, j = -1 , k = -1;
2885 for (i = 0; i < no_of_ip_proto; i++, pp = pp->
next) {
2890 for (k = 0; k < ip_proto[i].
no_of_port; k++, pp_port = pp_port->
next) {
2903 j++, pp_element = pp_element->
next) {
2915 if (pp_element != NULL)
2918 pp_element = pp_port->
sp;
2933 if (pp_element != NULL)
2936 if (pp_port != NULL)
2945 printf(
"i = %d, k = %d, j = %d(%s)\n", i, k, j, (dir == 0) ?
"ts" :
"tc");
2950static uint16_t ProbingParserDummyForTesting(
2951 const Flow *f, uint8_t direction,
const uint8_t *input, uint32_t input_len, uint8_t *rdir)
2956static int AppLayerProtoDetectTest15(
void)
2964 ProbingParserDummyForTesting, NULL);
2966 ProbingParserDummyForTesting, NULL);
2968 ProbingParserDummyForTesting, NULL);
2971 ProbingParserDummyForTesting, NULL);
2973 ProbingParserDummyForTesting, NULL);
2975 ProbingParserDummyForTesting, NULL);
2977 ProbingParserDummyForTesting, NULL);
2980 ProbingParserDummyForTesting, NULL);
2982 ProbingParserDummyForTesting, NULL);
2986 ProbingParserDummyForTesting, NULL);
2990 ProbingParserDummyForTesting, NULL);
2992 ProbingParserDummyForTesting, NULL);
2995 ProbingParserDummyForTesting, NULL);
2997 ProbingParserDummyForTesting, NULL);
2999 ProbingParserDummyForTesting, NULL);
3001 ProbingParserDummyForTesting, NULL);
3003 ProbingParserDummyForTesting, NULL);
3005 ProbingParserDummyForTesting, NULL);
3007 ProbingParserDummyForTesting, NULL);
3009 ProbingParserDummyForTesting, NULL);
3011 ProbingParserDummyForTesting, NULL);
3013 ProbingParserDummyForTesting, NULL);
3025 {
"smb",
ALPROTO_SMB, 80, 5, 6 }, {
"ftp",
ALPROTO_FTP, 80, 7, 10 },
3026 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3038 {
"dcerpc",
ALPROTO_DCERPC, 81, 9, 10 }, {
"jabber",
ALPROTO_JABBER, 0, 12, 23 },
3039 {
"irc",
ALPROTO_IRC, 0, 12, 14 }, {
"tls",
ALPROTO_TLS, 0, 12, 18 },
3052 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3062 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3072 {
"irc",
ALPROTO_IRC, 0, 12, 14 }, {
"tls",
ALPROTO_TLS, 0, 12, 18 },
3101 { 85, 23, 23, element_ts_85, element_tc_85,
3104 { 90, 23, 23, element_ts_90, element_tc_90,
3107 { 0, 23, 23, element_ts_0, element_tc_0,
3136 if (AppLayerProtoDetectPPTestData(alpd_ctx.
ctx_pp, ip_proto,
3150static int AppLayerProtoDetectTest16(
void)
3155 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3156 "User-Agent: Mozilla/1.0\r\n"
3157 "Cookie: hellocatch\r\n\r\n";
3158 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3172 printf(
"packet setup failed: ");
3176 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3178 printf(
"flow setup failed: ");
3182 f->
proto = IPPROTO_TCP;
3200 "(msg:\"Test content option\"; "
3212 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3217 if (http_state == NULL) {
3218 printf(
"no http state: ");
3226 printf(
"sig 1 didn't alert, but it should: ");
3233 if (det_ctx != NULL)
3249static int AppLayerProtoDetectTest17(
void)
3254 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3255 "User-Agent: Mozilla/1.0\r\n"
3256 "Cookie: hellocatch\r\n\r\n";
3257 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3271 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3275 f->
proto = IPPROTO_TCP;
3291 "(msg:\"http over non standar port\"; "
3303 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3308 if (http_state == NULL) {
3309 printf(
"no http state: ");
3317 printf(
"sig 1 didn't alert, but it should: ");
3326 if (det_ctx != NULL)
3342static int AppLayerProtoDetectTest18(
void)
3347 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3348 "User-Agent: Mozilla/1.0\r\n"
3349 "Cookie: hellocatch\r\n\r\n";
3350 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3364 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3368 f->
proto = IPPROTO_TCP;
3384 "(msg:\"Test content option\"; "
3396 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3401 if (http_state == NULL) {
3402 printf(
"no http state: ");
3410 printf(
"sig 1 alerted, but it should not (it's not ftp): ");
3418 if (det_ctx != NULL)
3434static int AppLayerProtoDetectTest19(
void)
3438 uint8_t http_buf1[] =
"MPUT one\r\n";
3439 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3453 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3457 f->
proto = IPPROTO_TCP;
3473 "(msg:\"http over non standar port\"; "
3483 STREAM_TOSERVER, http_buf1, http_buf1_len);
3485 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3493 printf(
"sig 1 alerted, but it should not (it's ftp): ");
3502 if (det_ctx != NULL)
3519 UtRegisterTest(
"AppLayerProtoDetectTest01", AppLayerProtoDetectTest01);
3520 UtRegisterTest(
"AppLayerProtoDetectTest02", AppLayerProtoDetectTest02);
3521 UtRegisterTest(
"AppLayerProtoDetectTest03", AppLayerProtoDetectTest03);
3522 UtRegisterTest(
"AppLayerProtoDetectTest04", AppLayerProtoDetectTest04);
3523 UtRegisterTest(
"AppLayerProtoDetectTest05", AppLayerProtoDetectTest05);
3524 UtRegisterTest(
"AppLayerProtoDetectTest06", AppLayerProtoDetectTest06);
3525 UtRegisterTest(
"AppLayerProtoDetectTest07", AppLayerProtoDetectTest07);
3526 UtRegisterTest(
"AppLayerProtoDetectTest08", AppLayerProtoDetectTest08);
3527 UtRegisterTest(
"AppLayerProtoDetectTest09", AppLayerProtoDetectTest09);
3528 UtRegisterTest(
"AppLayerProtoDetectTest10", AppLayerProtoDetectTest10);
3529 UtRegisterTest(
"AppLayerProtoDetectTest11", AppLayerProtoDetectTest11);
3530 UtRegisterTest(
"AppLayerProtoDetectTest12", AppLayerProtoDetectTest12);
3531 UtRegisterTest(
"AppLayerProtoDetectTest13", AppLayerProtoDetectTest13);
3532 UtRegisterTest(
"AppLayerProtoDetectTest14", AppLayerProtoDetectTest14);
3533 UtRegisterTest(
"AppLayerProtoDetectTest15", AppLayerProtoDetectTest15);
3534 UtRegisterTest(
"AppLayerProtoDetectTest16", AppLayerProtoDetectTest16);
3535 UtRegisterTest(
"AppLayerProtoDetectTest17", AppLayerProtoDetectTest17);
3536 UtRegisterTest(
"AppLayerProtoDetectTest18", AppLayerProtoDetectTest18);
3537 UtRegisterTest(
"AppLayerProtoDetectTest19", AppLayerProtoDetectTest19);
void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos)
struct AppLayerProtoDetectProbingParserPort_ AppLayerProtoDetectProbingParserPort
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
int SCAppLayerProtoDetectPPParseConfPorts(const char *ipproto_name, uint8_t ipproto, const char *alproto_name, AppProto alproto, uint16_t min_depth, uint16_t max_depth, ProbingParserFPtr ProbingParserTs, ProbingParserFPtr ProbingParserTc)
void SCAppLayerProtoDetectPPRegister(uint8_t ipproto, const char *portstr, AppProto alproto, uint16_t min_depth, uint16_t max_depth, uint8_t direction, ProbingParserFPtr ProbingParser1, ProbingParserFPtr ProbingParser2)
register parser at a port
struct AppLayerProtoDetectAliases_ AppLayerProtoDetectAliases
int SCAppLayerProtoDetectPMRegisterPatternCSwPP(uint8_t ipproto, AppProto alproto, const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction, ProbingParserFPtr PPFunc, uint16_t pp_min_depth, uint16_t pp_max_depth)
AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, Flow *f, const uint8_t *buf, uint32_t buflen, uint8_t ipproto, uint8_t flags, bool *reverse_flow)
Returns the app layer protocol given a buffer.
int AppLayerProtoDetectDeSetup(void)
Cleans up the app layer protocol detection phase.
int SCAppLayerProtoDetectConfProtoDetectionEnabledDefault(const char *ipproto, const char *alproto, bool default_enabled)
Given a protocol name, checks if proto detection is enabled in the conf file.
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos)
void AppLayerProtoDetectUnittestCtxBackup(void)
Backs up the internal context used by the app layer proto detection module.
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
int AppLayerProtoDetectSetup(void)
The first function to be called. This initializes a global protocol detection context.
struct AppLayerProtoDetectProbingParserElement_ AppLayerProtoDetectProbingParserElement
bool AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto)
request applayer to wrap up this protocol and rerun protocol detection.
int AppLayerProtoDetectPrepareState(void)
Prepares the internal state for protocol detection. This needs to be called once all the patterns and...
struct AppLayerProtoDetectProbingParser_ AppLayerProtoDetectProbingParser
struct AppLayerProtoDetectPMCtx_ AppLayerProtoDetectPMCtx
int SCAppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto, const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction)
Registers a case-insensitive pattern for protocol detection.
void SCAppLayerForceProtocolChange(Flow *f, AppProto new_proto)
Forces a flow app-layer protocol change. Happens for instance when a HTTP2 flow is seen as DOH2.
struct AppLayerProtoDetectCtxIpproto_ AppLayerProtoDetectCtxIpproto
struct AppLayerProtoDetectCtx_ AppLayerProtoDetectCtx
The app layer protocol detection context.
void AppLayerProtoDetectRegisterAlias(const char *proto_name, const char *proto_alias)
struct AppLayerProtoDetectPPTestDataPort_ AppLayerProtoDetectPPTestDataPort
const char * AppLayerProtoDetectGetProtoName(AppProto alproto)
void AppLayerProtoDetectUnittestsRegister(void)
Register unittests for app layer proto detection module.
int SCAppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
struct AppLayerProtoDetectPPTestDataIPProto_ AppLayerProtoDetectPPTestDataIPProto
int SCAppLayerProtoDetectPMRegisterPatternCS(uint8_t ipproto, AppProto alproto, const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction)
Registers a case-sensitive pattern for protocol detection.
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
void AppLayerProtoDetectUnittestCtxRestore(void)
Restores back the internal context used by the app layer proto detection module, that was previously ...
void AppLayerRegisterExpectationProto(uint8_t proto, AppProto alproto)
struct AppLayerProtoDetectPMSignature_ AppLayerProtoDetectPMSignature
struct AppLayerProtoDetectPPTestDataElement_ AppLayerProtoDetectPPTestDataElement
bool SCAppLayerRequestProtocolTLSUpgrade(Flow *f)
request applayer to wrap up this protocol and rerun protocol detection with expectation of TLS....
void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx)
Destroys the app layer protocol detection thread context.
AppProto(* ProbingParserFPtr)(const Flow *f, uint8_t flags, const uint8_t *input, uint32_t input_len, uint8_t *rdir)
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
AppProto StringToAppProto(const char *proto_name)
Maps a string to its ALPROTO_* equivalent.
SCConfNode * SCConfNodeLookupChild(const SCConfNode *node, const char *name)
Lookup a child configuration node by name.
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
int SCConfValIsTrue(const char *val)
Check if a value is true.
int SCConfValIsFalse(const char *val)
Check if a value is false.
DetectContentData * DetectContentParseEncloseQuotes(SpmGlobalThreadCtx *spm_global_thread_ctx, const char *contentstr)
void DetectContentFree(DetectEngineCtx *de_ctx, void *ptr)
this function will SCFree memory associated with DetectContentData
#define DETECT_CONTENT_NOCASE
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
int SigGroupCleanup(DetectEngineCtx *de_ctx)
uint8_t PatternMatchDefaultMatcher(void)
Function to return the multi pattern matcher algorithm to be used by the engine, based on the mpm-alg...
int DetectPortParse(const DetectEngineCtx *de_ctx, DetectPort **head, const char *str)
Function for parsing port strings.
void DetectPortCleanupList(const DetectEngineCtx *de_ctx, DetectPort *head)
Free a DetectPort list and each of its members.
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Data structures and function prototypes for keeping state for the detection engine.
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
TcpStreamCnf stream_config
uint8_t FlowGetReverseProtoMapping(uint8_t rproto)
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
void FlowSetChangeProtoFlag(Flow *f)
Set flag to indicate to change proto for the flow.
#define FLOW_SET_PM_DONE(f, dir)
#define FLOW_SET_PP_DONE(f, dir)
#define FLOW_RESET_PE_DONE(f, dir)
#define FLOW_PKT_TOSERVER
#define FLOW_IS_PP_DONE(f, dir)
#define FLOW_RESET_PM_DONE(f, dir)
#define FLOW_PKT_ESTABLISHED
#define FLOW_RESET_PP_DONE(f, dir)
#define FLOW_IS_PM_DONE(f, dir)
#define FLOW_IS_PE_DONE(f, dir)
#define FLOW_SET_PE_DONE(f, dir)
AppLayerParserThreadCtx * alp_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
AppProto AppLayerExpectationHandle(Flow *f, uint8_t flags)
void AppLayerExpectationSetup(void)
void StreamTcpFreeConfig(bool quiet)
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
struct AppLayerProtoDetectAliases_ * next
AppLayerProtoDetectPMCtx ctx_pm[2]
The app layer protocol detection context.
AppLayerProtoDetectProbingParser * ctx_pp
AppLayerProtoDetectCtxIpproto ctx_ipp[FLOW_PROTO_DEFAULT]
const char ** alproto_names
uint8_t * expectation_proto
SpmGlobalThreadCtx * spm_global_thread_ctx
size_t expectation_proto_len
AppLayerProtoDetectPMSignature * head
AppLayerProtoDetectPMSignature ** map
struct AppLayerProtoDetectPMSignature_ * next
const char * alproto_name
AppLayerProtoDetectPPTestDataPort * port
AppLayerProtoDetectPPTestDataElement * toserver_element
AppLayerProtoDetectPPTestDataElement * toclient_element
ProbingParserFPtr ProbingParserTs
struct AppLayerProtoDetectProbingParserElement_ * next
ProbingParserFPtr ProbingParserTc
AppLayerProtoDetectProbingParserElement * dp
AppLayerProtoDetectProbingParserElement * sp
struct AppLayerProtoDetectProbingParserPort_ * next
struct AppLayerProtoDetectProbingParser_ * next
AppLayerProtoDetectProbingParserPort * port
The app layer protocol detection thread context.
MpmThreadCtx mpm_tctx[FLOW_PROTO_DEFAULT][2]
SpmThreadCtx * spm_thread_ctx
main detection engine ctx
Port structure for detection engine.
struct DetectPort_ * next
AppProto alproto
application level protocol
uint32_t probing_parser_toclient_alproto_masks
AppLayerParserState * alparser
uint32_t probing_parser_toserver_alproto_masks
int(* Prepare)(MpmConfig *, struct MpmCtx_ *)
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
void(* DestroyCtx)(struct MpmCtx_ *)
structure for storing potential rule matches
uint32_t rule_id_array_cnt
Per thread variable structure.
#define SWAP_VARS(type, a, b)
int RunmodeIsUnittests(void)
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
#define SCReturnCT(x, type)
#define SCReturnPtr(x, type)
#define SCLogError(...)
Macro used to log ERROR messages.
#define SCRealloc(ptr, sz)
#define SCMemcmp(a, b, c)
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
int MpmAddPatternCS(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
void MpmDestroyThreadCtx(MpmThreadCtx *mpm_thread_ctx, const uint16_t matcher)
int MpmAddPatternCI(MpmCtx *mpm_ctx, const uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
void MpmInitThreadCtx(MpmThreadCtx *mpm_thread_ctx, uint16_t matcher)
void MpmInitCtx(MpmCtx *mpm_ctx, uint8_t matcher)
int PmqSetup(PrefilterRuleStore *pmq)
Setup a pmq.
void PmqReset(PrefilterRuleStore *pmq)
Reset a Pmq for reusage. Meant to be called after a single search.
void PmqFree(PrefilterRuleStore *pmq)
Cleanup and free a Pmq.
SpmThreadCtx * SpmMakeThreadCtx(const SpmGlobalThreadCtx *global_thread_ctx)
uint8_t SinglePatternMatchDefaultMatcher(void)
Returns the single pattern matcher algorithm to be used, based on the spm-algo setting in yaml.
void SpmDestroyGlobalThreadCtx(SpmGlobalThreadCtx *global_thread_ctx)
SpmGlobalThreadCtx * SpmInitGlobalThreadCtx(uint8_t matcher)
void SpmDestroyThreadCtx(SpmThreadCtx *thread_ctx)
SpmCtx * SpmInitCtx(const uint8_t *needle, uint16_t needle_len, int nocase, SpmGlobalThreadCtx *global_thread_ctx)
void SpmDestroyCtx(SpmCtx *ctx)
uint8_t * SpmScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, const uint8_t *haystack, uint32_t haystack_len)
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Packet * UTHBuildPacketSrcDstPorts(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, uint16_t sport, uint16_t dport)
UTHBuildPacketSrcDstPorts is a wrapper that build packets specifying src and dst ports and defaulting...
void UTHFreeFlow(Flow *flow)
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
#define DEBUG_VALIDATE_BUG_ON(exp)