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.");
1706 int ipproto_map = 0;
1713 for (dir = 0; dir < 2; dir++) {
1716 for (
id = 0;
id < pm_ctx->
max_sig_id;
id++) {
1717 sig = pm_ctx->
map[
id];
1718 AppLayerProtoDetectPMFreeSignature(sig);
1734 AppLayerProtoDetectFreeAliases();
1736 AppLayerProtoDetectFreeProbingParsers(alpd_ctx.
ctx_pp);
1748 FatalError(
"Unable to realloc alproto_names.");
1772 new_alias->
next = NULL;
1774 if (alpda_ctx == NULL) {
1775 alpda_ctx = new_alias;
1778 while (cur_alias->
next != NULL) {
1779 cur_alias = cur_alias->
next;
1781 cur_alias->
next = new_alias;
1845 if (new_proto != f->
alproto) {
1872 const char *ipproto,
const char *alproto,
bool default_enabled)
1876 BUG_ON(ipproto == NULL || alproto == NULL);
1886 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1888 default_enabled =
true;
1891 r = snprintf(param,
sizeof(param),
"%s%s%s",
"app-layer.protocols.",
1892 alproto,
".enabled");
1895 }
else if (r > (
int)
sizeof(param)) {
1896 FatalError(
"buffer not big enough to write param.");
1901 SCLogDebug(
"Entry for %s not found.", param);
1902 r = snprintf(param,
sizeof(param),
"%s%s%s%s%s",
"app-layer.protocols.",
1903 alproto,
".", ipproto,
".enabled");
1906 }
else if (r > (
int)
sizeof(param)) {
1907 FatalError(
"buffer not big enough to write param.");
1912 SCLogDebug(
"Entry for %s not found.", param);
1913 if (default_enabled) {
1926 }
else if (strcasecmp(node->
val,
"detection-only") == 0) {
1932 SCLogError(
"Invalid value found for %s.", param);
1957 for (j = 0; j < 2; j++) {
1958 if (max_pat_id == 0) {
1978 for (j = 0; j < 2; j++) {
2005 int ipproto_map, dir;
2008 for (dir = 0; dir < 2; dir++) {
2037 AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos);
2038 AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos);
2039 AppLayerProtoDetectPEGetIpprotos(alproto, ipprotos);
2050 while (cur_alias != NULL) {
2051 if (strcasecmp(alproto_name, cur_alias->
proto_alias) == 0) {
2055 cur_alias = cur_alias->
next;
2061 if (alpd_ctx.
alproto_names[a] != NULL && AppProtoEquals(b, a)) {
2097 alprotos[alproto] = 1;
2103 static void AppLayerProtoDetectPEGetIpprotos(
AppProto alproto,
2110 ipprotos[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);
2113 ipprotos[IPPROTO_UDP / 8] |= 1 << (IPPROTO_UDP % 8);
2121 SCLogError(
"Expectation on 2 IP protocols are not supported");
2139 alpd_ctx_ut = alpd_ctx;
2140 memset(&alpd_ctx, 0,
sizeof(alpd_ctx));
2147 alpd_ctx = alpd_ctx_ut;
2148 memset(&alpd_ctx_ut, 0,
sizeof(alpd_ctx_ut));
2152 static int AppLayerProtoDetectTest01(
void)
2157 const char *buf =
"HTTP";
2173 static int AppLayerProtoDetectTest02(
void)
2178 const char *buf =
"HTTP";
2199 static int AppLayerProtoDetectTest03(
void)
2204 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n";
2206 memset(pm_results, 0,
sizeof(pm_results));
2208 memset(&f, 0x00,
sizeof(f));
2212 const char *buf =
"HTTP";
2232 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2233 &f, l7data,
sizeof(l7data),
2235 pm_results, &rflow);
2245 static int AppLayerProtoDetectTest04(
void)
2250 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n";
2252 memset(&f, 0x00,
sizeof(f));
2254 memset(pm_results, 0,
sizeof(pm_results));
2257 const char *buf =
"200 ";
2274 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2275 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2286 static int AppLayerProtoDetectTest05(
void)
2291 uint8_t l7data[] =
"HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n<HTML><BODY>Blahblah</BODY></HTML>";
2293 memset(pm_results, 0,
sizeof(pm_results));
2295 memset(&f, 0x00,
sizeof(f));
2298 const char *buf =
"HTTP";
2318 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2319 &f, l7data,
sizeof(l7data),
2331 static int AppLayerProtoDetectTest06(
void)
2336 uint8_t l7data[] =
"220 Welcome to the OISF FTP server\r\n";
2338 memset(pm_results, 0,
sizeof(pm_results));
2340 memset(&f, 0x00,
sizeof(f));
2343 const char *buf =
"HTTP";
2363 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2364 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2375 static int AppLayerProtoDetectTest07(
void)
2380 uint8_t l7data[] =
"220 Welcome to the OISF HTTP/FTP server\r\n";
2382 memset(&f, 0x00,
sizeof(f));
2385 memset(pm_results, 0,
sizeof(pm_results));
2387 const char *buf =
"HTTP";
2403 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2404 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2414 static int AppLayerProtoDetectTest08(
void)
2419 uint8_t l7data[] = {
2420 0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, 0x42,
2421 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8,
2422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe,
2424 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02,
2425 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f,
2426 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52,
2427 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02,
2428 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e,
2429 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f,
2430 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57,
2431 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70,
2432 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 0x02,
2433 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30,
2434 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41,
2435 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54,
2436 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32,
2440 memset(pm_results, 0,
sizeof(pm_results));
2442 memset(&f, 0x00,
sizeof(f));
2445 const char *buf =
"|ff|SMB";
2461 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2462 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2473 static int AppLayerProtoDetectTest09(
void)
2478 uint8_t l7data[] = {
2479 0x00, 0x00, 0x00, 0x66, 0xfe, 0x53, 0x4d, 0x42,
2480 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2481 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
2482 0x00, 0x00, 0x00, 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, 0x24, 0x00, 0x01, 0x00,
2488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
2495 memset(pm_results, 0,
sizeof(pm_results));
2497 memset(&f, 0x00,
sizeof(f));
2500 const char *buf =
"|fe|SMB";
2516 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2517 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2528 static int AppLayerProtoDetectTest10(
void)
2533 uint8_t l7data[] = {
2534 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
2535 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2536 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00,
2537 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
2538 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11,
2539 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57,
2540 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
2541 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
2542 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00
2545 memset(pm_results, 0,
sizeof(pm_results));
2547 memset(&f, 0x00,
sizeof(f));
2550 const char *buf =
"|05 00|";
2567 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2568 &f, l7data,
sizeof(l7data), STREAM_TOCLIENT,
2583 static int AppLayerProtoDetectTest11(
void)
2588 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2589 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2591 memset(pm_results, 0,
sizeof(pm_results));
2593 memset(&f, 0x00,
sizeof(f));
2605 IPPROTO_TCP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2607 IPPROTO_TCP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2609 IPPROTO_TCP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2634 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2635 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2640 memset(pm_results, 0,
sizeof(pm_results));
2642 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2656 static int AppLayerProtoDetectTest12(
void)
2668 printf(
"failure 1\n");
2674 printf(
"failure 2\n");
2680 printf(
"failure 3\n");
2684 printf(
"failure 4\n");
2688 printf(
"failure 5\n");
2692 printf(
"failure 6\n");
2708 static int AppLayerProtoDetectTest13(
void)
2713 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2714 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2718 memset(&f, 0x00,
sizeof(f));
2730 IPPROTO_UDP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2732 IPPROTO_UDP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2734 IPPROTO_UDP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2755 memset(pm_results, 0,
sizeof(pm_results));
2757 uint32_t
cnt = AppLayerProtoDetectPMGetProto(
alpd_tctx,
2758 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2762 memset(pm_results, 0,
sizeof(pm_results));
2764 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2779 static int AppLayerProtoDetectTest14(
void)
2784 uint8_t l7data[] =
"CONNECT www.ssllabs.com:443 HTTP/1.0\r\n";
2785 uint8_t l7data_resp[] =
"HTTP/1.1 405 Method Not Allowed\r\n";
2789 memset(&f, 0x00,
sizeof(f));
2801 IPPROTO_UDP,
ALPROTO_HTTP1,
"TRACE", 5, 0, STREAM_TOSERVER);
2803 IPPROTO_UDP,
ALPROTO_HTTP1,
"OPTIONS", 7, 0, STREAM_TOSERVER);
2805 IPPROTO_UDP,
ALPROTO_HTTP1,
"CONNECT", 7, 0, STREAM_TOSERVER);
2827 memset(pm_results, 0,
sizeof(pm_results));
2830 &f, l7data,
sizeof(l7data), STREAM_TOSERVER,
2835 memset(pm_results, 0,
sizeof(pm_results));
2837 &f, l7data_resp,
sizeof(l7data_resp), STREAM_TOCLIENT,
2880 int i = -1, j = -1 , k = -1;
2884 for (i = 0; i < no_of_ip_proto; i++, pp = pp->
next) {
2885 if (pp->ipproto != ip_proto[i].
ipproto)
2889 for (k = 0; k < ip_proto[i].
no_of_port; k++, pp_port = pp_port->
next) {
2890 if (pp_port->port != ip_proto[i].
port[k].
port)
2902 j++, pp_element = pp_element->
next) {
2914 if (pp_element != NULL)
2917 pp_element = pp_port->sp;
2932 if (pp_element != NULL)
2935 if (pp_port != NULL)
2944 printf(
"i = %d, k = %d, j = %d(%s)\n", i, k, j, (dir == 0) ?
"ts" :
"tc");
2949 static uint16_t ProbingParserDummyForTesting(
2950 const Flow *f, uint8_t direction,
const uint8_t *input, uint32_t input_len, uint8_t *rdir)
2955 static int AppLayerProtoDetectTest15(
void)
2963 ProbingParserDummyForTesting, NULL);
2965 ProbingParserDummyForTesting, NULL);
2967 ProbingParserDummyForTesting, NULL);
2970 ProbingParserDummyForTesting, NULL);
2972 ProbingParserDummyForTesting, NULL);
2974 ProbingParserDummyForTesting, NULL);
2976 ProbingParserDummyForTesting, NULL);
2979 ProbingParserDummyForTesting, NULL);
2981 ProbingParserDummyForTesting, NULL);
2985 ProbingParserDummyForTesting, NULL);
2989 ProbingParserDummyForTesting, NULL);
2991 ProbingParserDummyForTesting, NULL);
2994 ProbingParserDummyForTesting, NULL);
2996 ProbingParserDummyForTesting, NULL);
2998 ProbingParserDummyForTesting, NULL);
3000 ProbingParserDummyForTesting, NULL);
3002 ProbingParserDummyForTesting, NULL);
3004 ProbingParserDummyForTesting, NULL);
3006 ProbingParserDummyForTesting, NULL);
3008 ProbingParserDummyForTesting, NULL);
3010 ProbingParserDummyForTesting, NULL);
3012 ProbingParserDummyForTesting, NULL);
3024 {
"smb",
ALPROTO_SMB, 80, 5, 6 }, {
"ftp",
ALPROTO_FTP, 80, 7, 10 },
3025 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3037 {
"dcerpc",
ALPROTO_DCERPC, 81, 9, 10 }, {
"jabber",
ALPROTO_JABBER, 0, 12, 23 },
3038 {
"irc",
ALPROTO_IRC, 0, 12, 14 }, {
"tls",
ALPROTO_TLS, 0, 12, 18 },
3051 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3061 {
"jabber",
ALPROTO_JABBER, 0, 12, 23 }, {
"irc",
ALPROTO_IRC, 0, 12, 14 },
3071 {
"irc",
ALPROTO_IRC, 0, 12, 14 }, {
"tls",
ALPROTO_TLS, 0, 12, 18 },
3100 { 85, 23, 23, element_ts_85, element_tc_85,
3103 { 90, 23, 23, element_ts_90, element_tc_90,
3106 { 0, 23, 23, element_ts_0, element_tc_0,
3135 if (AppLayerProtoDetectPPTestData(alpd_ctx.
ctx_pp, ip_proto,
3149 static int AppLayerProtoDetectTest16(
void)
3154 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3155 "User-Agent: Mozilla/1.0\r\n"
3156 "Cookie: hellocatch\r\n\r\n";
3157 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3171 printf(
"packet setup failed: ");
3175 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3177 printf(
"flow setup failed: ");
3181 f->
proto = IPPROTO_TCP;
3199 "(msg:\"Test content option\"; "
3211 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3216 if (http_state == NULL) {
3217 printf(
"no http state: ");
3225 printf(
"sig 1 didn't alert, but it should: ");
3232 if (det_ctx != NULL)
3248 static int AppLayerProtoDetectTest17(
void)
3253 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3254 "User-Agent: Mozilla/1.0\r\n"
3255 "Cookie: hellocatch\r\n\r\n";
3256 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3270 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3274 f->
proto = IPPROTO_TCP;
3290 "(msg:\"http over non standar port\"; "
3302 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3307 if (http_state == NULL) {
3308 printf(
"no http state: ");
3316 printf(
"sig 1 didn't alert, but it should: ");
3325 if (det_ctx != NULL)
3341 static int AppLayerProtoDetectTest18(
void)
3346 uint8_t http_buf1[] =
"POST /one HTTP/1.0\r\n"
3347 "User-Agent: Mozilla/1.0\r\n"
3348 "Cookie: hellocatch\r\n\r\n";
3349 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3363 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3367 f->
proto = IPPROTO_TCP;
3383 "(msg:\"Test content option\"; "
3395 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3400 if (http_state == NULL) {
3401 printf(
"no http state: ");
3409 printf(
"sig 1 alerted, but it should not (it's not ftp): ");
3417 if (det_ctx != NULL)
3433 static int AppLayerProtoDetectTest19(
void)
3437 uint8_t http_buf1[] =
"MPUT one\r\n";
3438 uint32_t http_buf1_len =
sizeof(http_buf1) - 1;
3452 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3456 f->
proto = IPPROTO_TCP;
3472 "(msg:\"http over non standar port\"; "
3482 STREAM_TOSERVER, http_buf1, http_buf1_len);
3484 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3492 printf(
"sig 1 alerted, but it should not (it's ftp): ");
3501 if (det_ctx != NULL)
3518 UtRegisterTest(
"AppLayerProtoDetectTest01", AppLayerProtoDetectTest01);
3519 UtRegisterTest(
"AppLayerProtoDetectTest02", AppLayerProtoDetectTest02);
3520 UtRegisterTest(
"AppLayerProtoDetectTest03", AppLayerProtoDetectTest03);
3521 UtRegisterTest(
"AppLayerProtoDetectTest04", AppLayerProtoDetectTest04);
3522 UtRegisterTest(
"AppLayerProtoDetectTest05", AppLayerProtoDetectTest05);
3523 UtRegisterTest(
"AppLayerProtoDetectTest06", AppLayerProtoDetectTest06);
3524 UtRegisterTest(
"AppLayerProtoDetectTest07", AppLayerProtoDetectTest07);
3525 UtRegisterTest(
"AppLayerProtoDetectTest08", AppLayerProtoDetectTest08);
3526 UtRegisterTest(
"AppLayerProtoDetectTest09", AppLayerProtoDetectTest09);
3527 UtRegisterTest(
"AppLayerProtoDetectTest10", AppLayerProtoDetectTest10);
3528 UtRegisterTest(
"AppLayerProtoDetectTest11", AppLayerProtoDetectTest11);
3529 UtRegisterTest(
"AppLayerProtoDetectTest12", AppLayerProtoDetectTest12);
3530 UtRegisterTest(
"AppLayerProtoDetectTest13", AppLayerProtoDetectTest13);
3531 UtRegisterTest(
"AppLayerProtoDetectTest14", AppLayerProtoDetectTest14);
3532 UtRegisterTest(
"AppLayerProtoDetectTest15", AppLayerProtoDetectTest15);
3533 UtRegisterTest(
"AppLayerProtoDetectTest16", AppLayerProtoDetectTest16);
3534 UtRegisterTest(
"AppLayerProtoDetectTest17", AppLayerProtoDetectTest17);
3535 UtRegisterTest(
"AppLayerProtoDetectTest18", AppLayerProtoDetectTest18);
3536 UtRegisterTest(
"AppLayerProtoDetectTest19", AppLayerProtoDetectTest19);