190 static 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;
528 static 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]);
686 static 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;
1140 static 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)
1338 static 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);
1460 static 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;
2104 static 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));
2153 static int AppLayerProtoDetectTest01(
void)
2158 const char *buf =
"HTTP";
2174 static int AppLayerProtoDetectTest02(
void)
2179 const char *buf =
"HTTP";
2200 static 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);
2246 static 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,
2287 static 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),
2332 static 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,
2376 static 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,
2415 static 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,
2474 static 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,
2529 static 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,
2584 static 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,
2657 static 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");
2709 static 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,
2780 static 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) {
2886 if (pp->ipproto != ip_proto[i].
ipproto)
2890 for (k = 0; k < ip_proto[i].
no_of_port; k++, pp_port = pp_port->
next) {
2891 if (pp_port->port != ip_proto[i].
port[k].
port)
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");
2950 static uint16_t ProbingParserDummyForTesting(
2951 const Flow *f, uint8_t direction,
const uint8_t *input, uint32_t input_len, uint8_t *rdir)
2956 static 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,
3150 static 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)
3249 static 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)
3342 static 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)
3434 static 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);