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; ) {
1271 ctx->map[s->
id] = s;
1313 AppProto alproto, uint8_t direction,
1315 uint16_t pp_min_depth, uint16_t pp_max_depth)
1337 static int AppLayerProtoDetectPMRegisterPattern(uint8_t ipproto,
AppProto alproto,
1338 const char *pattern,
1339 uint16_t depth, uint16_t
offset,
1343 uint16_t pp_min_depth, uint16_t pp_max_depth)
1367 if (depth < cd->content_len)
1370 if (direction & STREAM_TOSERVER)
1377 if (depth < ctx_pm->min_len)
1381 AppLayerProtoDetectPMAddSignature(ctx_pm, cd, alproto, direction,
1382 PPFunc, pp_min_depth, pp_max_depth);
1395 const uint8_t *buf, uint32_t buflen, uint8_t ipproto, uint8_t
flags,
bool *reverse_flow)
1398 SCLogDebug(
"buflen %u for %s direction", buflen,
1399 (
flags & STREAM_TOSERVER) ?
"toserver" :
"toclient");
1405 uint16_t pm_matches = AppLayerProtoDetectPMGetProto(
1406 tctx, f, buf, buflen,
flags, pm_results, reverse_flow);
1407 if (pm_matches > 0) {
1409 alproto = pm_results[0];
1412 uint8_t reverse_dir = (
flags & STREAM_TOSERVER) ? STREAM_TOCLIENT : STREAM_TOSERVER;
1425 alproto = AppLayerProtoDetectPPGetProto(f, buf, buflen, ipproto,
flags, reverse_flow);
1426 if (AppProtoIsValid(alproto)) {
1434 alproto = AppLayerProtoDetectPEGetProto(f,
flags);
1449 while (pp != NULL) {
1451 AppLayerProtoDetectProbingParserFree(pp);
1459 static void AppLayerProtoDetectFreeAliases(
void)
1464 if (cur_alias == NULL)
1468 while (cur_alias != NULL) {
1469 next_alias = cur_alias->
next;
1471 cur_alias = next_alias;
1491 for (j = 0; j < 2; j++) {
1494 if (AppLayerProtoDetectPMSetContentIDs(ctx_pm) < 0)
1500 if (AppLayerProtoDetectPMMapSignatures(ctx_pm) < 0)
1502 if (AppLayerProtoDetectPMPrepareMpm(ctx_pm) < 0)
1509 AppLayerProtoDetectPrintProbingParsers(alpd_ctx.
ctx_pp);
1527 uint16_t min_depth, uint16_t max_depth, uint8_t direction,
ProbingParserFPtr ProbingParser1,
1533 if (portstr == NULL) {
1536 AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.
ctx_pp, ipproto,
false, 0, alproto,
1537 min_depth, max_depth, direction, ProbingParser1, ProbingParser2);
1542 while (temp_dp != NULL) {
1543 uint16_t port = temp_dp->
port;
1544 if (port == 0 && temp_dp->
port2 != 0)
1547 AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.
ctx_pp, ipproto,
true, port,
1548 alproto, min_depth, max_depth, direction, ProbingParser1, ProbingParser2);
1549 if (port == temp_dp->
port2) {
1555 temp_dp = temp_dp->
next;
1563 const char *alproto_name,
AppProto alproto, uint16_t min_depth, uint16_t max_depth,
1574 r = snprintf(param,
sizeof(param),
"%s%s%s",
"app-layer.protocols.",
1575 alproto_name,
".detection-ports");
1578 }
else if (r > (
int)
sizeof(param)) {
1579 FatalError(
"buffer not big enough to write param.");
1583 SCLogDebug(
"Entry for %s not found.", param);
1584 r = snprintf(param,
sizeof(param),
"%s%s%s%s%s",
"app-layer.protocols.",
1585 alproto_name,
".", ipproto_name,
".detection-ports");
1588 }
else if (r > (
int)
sizeof(param)) {
1589 FatalError(
"buffer not big enough to write param.");
1598 if (port_node == NULL)
1601 if (port_node != NULL && port_node->
val != NULL) {
1604 ProbingParserTs, ProbingParserTc);
1609 if (port_node == NULL)
1612 if (port_node != NULL && port_node->
val != NULL) {
1615 ProbingParserTc, ProbingParserTs);
1626 uint16_t depth, uint16_t
offset, uint8_t direction)
1629 int r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto,
1637 const char *pattern, uint16_t depth, uint16_t
offset, uint8_t direction,
1641 int r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto,
1644 PPFunc, pp_min_depth, pp_max_depth);
1649 uint16_t depth, uint16_t
offset, uint8_t direction)
1652 int r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto,
1667 memset(&alpd_ctx, 0,
sizeof(alpd_ctx));
1674 FatalError(
"Unable to alloc SpmGlobalThreadCtx.");
1678 for (j = 0; j < 2; j++) {
1685 FatalError(
"Unable to alloc alproto_names.");
1691 FatalError(
"Unable to alloc expectation_proto.");
1722 int ipproto_map = 0;
1729 for (dir = 0; dir < 2; dir++) {
1732 for (
id = 0;
id < pm_ctx->
max_sig_id;
id++) {
1733 sig = pm_ctx->
map[
id];
1734 AppLayerProtoDetectPMFreeSignature(sig);
1750 AppLayerProtoDetectFreeAliases();
1752 AppLayerProtoDetectFreeProbingParsers(alpd_ctx.
ctx_pp);
1764 FatalError(
"Unable to realloc alproto_names.");
1788 new_alias->
next = NULL;
1790 if (alpda_ctx == NULL) {
1791 alpda_ctx = new_alias;
1794 while (cur_alias->
next != NULL) {
1795 cur_alias = cur_alias->
next;
1797 cur_alias->
next = new_alias;
1861 if (new_proto != f->
alproto) {
1888 const char *ipproto,
const char *alproto,
bool default_enabled)
1892 BUG_ON(ipproto == NULL || alproto == NULL);
1902 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1904 default_enabled =
true;
1907 r = snprintf(param,
sizeof(param),
"%s%s%s",
"app-layer.protocols.",
1908 alproto,
".enabled");
1911 }
else if (r > (
int)
sizeof(param)) {
1912 FatalError(
"buffer not big enough to write param.");
1917 SCLogDebug(
"Entry for %s not found.", param);
1918 r = snprintf(param,
sizeof(param),
"%s%s%s%s%s",
"app-layer.protocols.",
1919 alproto,
".", ipproto,
".enabled");
1922 }
else if (r > (
int)
sizeof(param)) {
1923 FatalError(
"buffer not big enough to write param.");
1928 SCLogDebug(
"Entry for %s not found.", param);
1929 if (default_enabled) {
1942 }
else if (strcasecmp(node->
val,
"detection-only") == 0) {
1948 SCLogError(
"Invalid value found for %s.", param);
1973 for (j = 0; j < 2; j++) {
1974 if (max_pat_id == 0) {
1994 for (j = 0; j < 2; j++) {
2021 int ipproto_map, dir;
2024 for (dir = 0; dir < 2; dir++) {
2053 AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos);
2054 AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos);
2055 AppLayerProtoDetectPEGetIpprotos(alproto, ipprotos);
2066 while (cur_alias != NULL) {
2067 if (strcasecmp(alproto_name, cur_alias->
proto_alias) == 0) {
2071 cur_alias = cur_alias->
next;
2077 if (alpd_ctx.
alproto_names[a] != NULL && AppProtoEquals(b, a)) {
2113 alprotos[alproto] = 1;
2119 static void AppLayerProtoDetectPEGetIpprotos(
AppProto alproto,
2126 ipprotos[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);
2129 ipprotos[IPPROTO_UDP / 8] |= 1 << (IPPROTO_UDP % 8);
2137 SCLogError(
"Expectation on 2 IP protocols are not supported");
2155 alpd_ctx_ut = alpd_ctx;
2156 memset(&alpd_ctx, 0,
sizeof(alpd_ctx));
2163 alpd_ctx = alpd_ctx_ut;
2164 memset(&alpd_ctx_ut, 0,
sizeof(alpd_ctx_ut));
2168 static int AppLayerProtoDetectTest01(
void)
2173 const char *buf =
"HTTP";
2189 static int AppLayerProtoDetectTest02(
void)
2194 const char *buf =
"HTTP";
2215 static int AppLayerProtoDetectTest03(
void)
2220 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n";
2222 memset(pm_results, 0,
sizeof(pm_results));
2224 memset(&f, 0x00,
sizeof(f));
2228 const char *buf =
"HTTP";
2248 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2249 &f, l7data,
sizeof(l7data),
2251 pm_results, &rflow);
2261 static int AppLayerProtoDetectTest04(
void)
2266 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n";
2268 memset(&f, 0x00,
sizeof(f));
2270 memset(pm_results, 0,
sizeof(pm_results));
2273 const char *buf =
"200 ";
2290 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2291 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2302 static int AppLayerProtoDetectTest05(
void)
2307 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n<HTML><BODY>Blahblah</BODY></HTML>";
2309 memset(pm_results, 0,
sizeof(pm_results));
2311 memset(&f, 0x00,
sizeof(f));
2314 const char *buf =
"HTTP";
2334 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2335 &f, l7data,
sizeof(l7data),
2347 static int AppLayerProtoDetectTest06(
void)
2352 uint8_t l7data[] =
"220 Welcome to the OISF FTP server\r\n";
2354 memset(pm_results, 0,
sizeof(pm_results));
2356 memset(&f, 0x00,
sizeof(f));
2359 const char *buf =
"HTTP";
2379 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2380 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2391 static int AppLayerProtoDetectTest07(
void)
2396 uint8_t l7data[] =
"220 Welcome to the OISF HTTP/FTP server\r\n";
2398 memset(&f, 0x00,
sizeof(f));
2401 memset(pm_results, 0,
sizeof(pm_results));
2403 const char *buf =
"HTTP";
2419 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2420 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2430 static int AppLayerProtoDetectTest08(
void)
2435 uint8_t l7data[] = {
2436 0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, 0x42,
2437 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8,
2438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe,
2440 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02,
2441 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f,
2442 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52,
2443 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02,
2444 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e,
2445 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f,
2446 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57,
2447 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70,
2448 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 0x02,
2449 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30,
2450 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41,
2451 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54,
2452 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32,
2456 memset(pm_results, 0,
sizeof(pm_results));
2458 memset(&f, 0x00,
sizeof(f));
2461 const char *buf =
"|ff|SMB";
2477 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2478 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2489 static int AppLayerProtoDetectTest09(
void)
2494 uint8_t l7data[] = {
2495 0x00, 0x00, 0x00, 0x66, 0xfe, 0x53, 0x4d, 0x42,
2496 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2497 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
2498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2503 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x00,
2504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2511 memset(pm_results, 0,
sizeof(pm_results));
2513 memset(&f, 0x00,
sizeof(f));
2516 const char *buf =
"|fe|SMB";
2532 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2533 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2544 static int AppLayerProtoDetectTest10(
void)
2549 uint8_t l7data[] = {
2550 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
2551 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2552 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00,
2553 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
2554 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11,
2555 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57,
2556 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
2557 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
2558 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00
2561 memset(pm_results, 0,
sizeof(pm_results));
2563 memset(&f, 0x00,
sizeof(f));
2566 const char *buf =
"|05 00|";
2583 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2584 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2599 static int AppLayerProtoDetectTest11(
void)
2604 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2605 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2607 memset(pm_results, 0,
sizeof(pm_results));
2609 memset(&f, 0x00,
sizeof(f));
2621 IPPROTO_TCP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2623 IPPROTO_TCP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2625 IPPROTO_TCP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2650 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2651 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2656 memset(pm_results, 0,
sizeof(pm_results));
2658 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2672 static int AppLayerProtoDetectTest12(
void)
2684 printf(
"failure 1\n");
2690 printf(
"failure 2\n");
2696 printf(
"failure 3\n");
2700 printf(
"failure 4\n");
2704 printf(
"failure 5\n");
2708 printf(
"failure 6\n");
2724 static int AppLayerProtoDetectTest13(
void)
2729 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2730 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2734 memset(&f, 0x00,
sizeof(f));
2746 IPPROTO_UDP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2748 IPPROTO_UDP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2750 IPPROTO_UDP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2771 memset(pm_results, 0,
sizeof(pm_results));
2773 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2774 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2778 memset(pm_results, 0,
sizeof(pm_results));
2780 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2795 static int AppLayerProtoDetectTest14(
void)
2800 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2801 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2805 memset(&f, 0x00,
sizeof(f));
2817 IPPROTO_UDP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2819 IPPROTO_UDP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2821 IPPROTO_UDP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2843 memset(pm_results, 0,
sizeof(pm_results));
2846 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2851 memset(pm_results, 0,
sizeof(pm_results));
2853 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2896 int i = -1, j = -1 , k = -1;
2900 for (i = 0; i < no_of_ip_proto; i++, pp = pp->
next) {
2901 if (pp->ipproto != ip_proto[i].
ipproto)
2905 for (k = 0; k < ip_proto[i].
no_of_port; k++, pp_port = pp_port->
next) {
2906 if (pp_port->port != ip_proto[i].
port[k].
port)
2918 j++, pp_element = pp_element->
next) {
2930 if (pp_element != NULL)
2933 pp_element = pp_port->sp;
2948 if (pp_element != NULL)
2951 if (pp_port != NULL)
2960 printf(
"i = %d, k = %d, j = %d(%s)\n", i, k, j, (dir == 0) ?
"ts" :
"tc");
2965 static uint16_t ProbingParserDummyForTesting(
2966 const Flow *f, uint8_t direction,
const uint8_t *input, uint32_t input_len, uint8_t *rdir)
2971 static int AppLayerProtoDetectTest15(
void)
2979 ProbingParserDummyForTesting, NULL);
2981 ProbingParserDummyForTesting, NULL);
2983 ProbingParserDummyForTesting, NULL);
2986 ProbingParserDummyForTesting, NULL);
2988 ProbingParserDummyForTesting, NULL);
2990 ProbingParserDummyForTesting, NULL);
2992 ProbingParserDummyForTesting, NULL);
2995 ProbingParserDummyForTesting, NULL);
2997 ProbingParserDummyForTesting, NULL);
3001 ProbingParserDummyForTesting, NULL);
3005 ProbingParserDummyForTesting, NULL);
3007 ProbingParserDummyForTesting, NULL);
3010 ProbingParserDummyForTesting, NULL);
3012 ProbingParserDummyForTesting, NULL);
3014 ProbingParserDummyForTesting, NULL);
3016 ProbingParserDummyForTesting, NULL);
3018 ProbingParserDummyForTesting, NULL);
3020 ProbingParserDummyForTesting, NULL);
3022 ProbingParserDummyForTesting, NULL);
3024 ProbingParserDummyForTesting, NULL);
3026 ProbingParserDummyForTesting, NULL);
3028 ProbingParserDummyForTesting, NULL);
3040 {
"smb",
ALPROTO_SMB, 80, 5, 6 }, {
"ftp",
ALPROTO_FTP, 80, 7, 10 },
3041 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3053 {
"dcerpc",
ALPROTO_DCERPC, 81, 9, 10 }, {
"jabber",
ALPROTO_JABBER, 0, 12, 23 },
3054 {
"irc",
ALPROTO_IRC, 0, 12, 14 }, {
"tls",
ALPROTO_TLS, 0, 12, 18 },
3067 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3077 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3087 {
"irc",
ALPROTO_IRC, 0, 12, 14 }, {
"tls",
ALPROTO_TLS, 0, 12, 18 },
3116 { 85, 23, 23, element_ts_85, element_tc_85,
3119 { 90, 23, 23, element_ts_90, element_tc_90,
3122 { 0, 23, 23, element_ts_0, element_tc_0,
3151 if (AppLayerProtoDetectPPTestData(alpd_ctx.
ctx_pp, ip_proto,
3165 static int AppLayerProtoDetectTest16(
void)
3170 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3171 "User-Agent: Mozilla/1.0\r\n"
3172 "Cookie: hellocatch\r\n\r\n";
3173 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3188 printf(
"packet setup failed: ");
3192 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3194 printf(
"flow setup failed: ");
3198 f->
proto = IPPROTO_TCP;
3216 "(msg:\"Test content option\"; "
3228 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3233 if (http_state == NULL) {
3234 printf(
"no http state: ");
3242 printf(
"sig 1 didn't alert, but it should: ");
3251 if (det_ctx != NULL)
3262 static int AppLayerProtoDetectTest17(
void)
3267 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3268 "User-Agent: Mozilla/1.0\r\n"
3269 "Cookie: hellocatch\r\n\r\n";
3270 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3285 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3289 f->
proto = IPPROTO_TCP;
3305 "(msg:\"http over non standar port\"; "
3317 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3322 if (http_state == NULL) {
3323 printf(
"no http state: ");
3331 printf(
"sig 1 didn't alert, but it should: ");
3342 if (det_ctx != NULL)
3353 static int AppLayerProtoDetectTest18(
void)
3358 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3359 "User-Agent: Mozilla/1.0\r\n"
3360 "Cookie: hellocatch\r\n\r\n";
3361 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3376 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3380 f->
proto = IPPROTO_TCP;
3396 "(msg:\"Test content option\"; "
3408 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3413 if (http_state == NULL) {
3414 printf(
"no http state: ");
3422 printf(
"sig 1 alerted, but it should not (it's not ftp): ");
3432 if (det_ctx != NULL)
3443 static int AppLayerProtoDetectTest19(
void)
3447 uint8_t http_buf1[] =
"MPUT one\r\n";
3448 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3463 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3467 f->
proto = IPPROTO_TCP;
3483 "(msg:\"http over non standar port\"; "
3493 STREAM_TOSERVER, http_buf1, http_buf1_len);
3495 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3503 printf(
"sig 1 alerted, but it should not (it's ftp): ");
3514 if (det_ctx != NULL)
3527 UtRegisterTest(
"AppLayerProtoDetectTest01", AppLayerProtoDetectTest01);
3528 UtRegisterTest(
"AppLayerProtoDetectTest02", AppLayerProtoDetectTest02);
3529 UtRegisterTest(
"AppLayerProtoDetectTest03", AppLayerProtoDetectTest03);
3530 UtRegisterTest(
"AppLayerProtoDetectTest04", AppLayerProtoDetectTest04);
3531 UtRegisterTest(
"AppLayerProtoDetectTest05", AppLayerProtoDetectTest05);
3532 UtRegisterTest(
"AppLayerProtoDetectTest06", AppLayerProtoDetectTest06);
3533 UtRegisterTest(
"AppLayerProtoDetectTest07", AppLayerProtoDetectTest07);
3534 UtRegisterTest(
"AppLayerProtoDetectTest08", AppLayerProtoDetectTest08);
3535 UtRegisterTest(
"AppLayerProtoDetectTest09", AppLayerProtoDetectTest09);
3536 UtRegisterTest(
"AppLayerProtoDetectTest10", AppLayerProtoDetectTest10);
3537 UtRegisterTest(
"AppLayerProtoDetectTest11", AppLayerProtoDetectTest11);
3538 UtRegisterTest(
"AppLayerProtoDetectTest12", AppLayerProtoDetectTest12);
3539 UtRegisterTest(
"AppLayerProtoDetectTest13", AppLayerProtoDetectTest13);
3540 UtRegisterTest(
"AppLayerProtoDetectTest14", AppLayerProtoDetectTest14);
3541 UtRegisterTest(
"AppLayerProtoDetectTest15", AppLayerProtoDetectTest15);
3542 UtRegisterTest(
"AppLayerProtoDetectTest16", AppLayerProtoDetectTest16);
3543 UtRegisterTest(
"AppLayerProtoDetectTest17", AppLayerProtoDetectTest17);
3544 UtRegisterTest(
"AppLayerProtoDetectTest18", AppLayerProtoDetectTest18);
3545 UtRegisterTest(
"AppLayerProtoDetectTest19", AppLayerProtoDetectTest19);