proto-detect: update port logic

If a flow matches both an 'sp' based PP registration and a 'dp' based,
until now we would only check the 'dp' one. This patch changes that. It
will inspect both.
pull/941/head
Victor Julien 11 years ago
parent eae5b1ba35
commit 8252416c10

@ -319,51 +319,73 @@ static AppProto AppLayerProtoDetectPPGetProto(Flow *f,
uint8_t *buf, uint32_t buflen,
uint8_t ipproto, uint8_t direction)
{
const AppLayerProtoDetectProbingParserPort *pp_port = NULL;
const AppLayerProtoDetectProbingParserPort *pp_port_dp = NULL;
const AppLayerProtoDetectProbingParserPort *pp_port_sp = NULL;
const AppLayerProtoDetectProbingParserElement *pe = NULL;
const AppLayerProtoDetectProbingParserElement *pe1 = NULL;
const AppLayerProtoDetectProbingParserElement *pe2 = NULL;
AppProto alproto = ALPROTO_UNKNOWN;
uint32_t *alproto_masks;
uint32_t mask = 0;
if (direction & STREAM_TOSERVER) {
/* first try the destination port */
pp_port = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp);
pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp);
alproto_masks = &f->probing_parser_toserver_alproto_masks;
if (pp_port == NULL) {
if (pp_port_dp != NULL) {
SCLogDebug("toserver - Probing parser found for destination port %"PRIu16, f->dp);
/* found based on destination port, so use dp registration */
pe1 = pp_port_dp->dp;
} else {
SCLogDebug("toserver - No probing parser registered for dest port %"PRIu16,
f->dp);
}
/* dp not found, lets try source port then */
pp_port = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp);
if (pp_port == NULL) {
SCLogDebug("toserver - No probing parser registered for source port %"PRIu16,
f->sp);
FLOW_SET_PP_DONE(f, direction);
goto end;
}
pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp);
if (pp_port_sp != NULL) {
SCLogDebug("toserver - Probing parser found for source port %"PRIu16, f->sp);
/* found based on source port, so use sp registration */
pe2 = pp_port_sp->sp;
} else {
SCLogDebug("toserver - No probing parser registered for source port %"PRIu16,
f->sp);
}
pe = pp_port->dp;
} else {
/* first try the destination port */
pp_port = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp);
pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp);
alproto_masks = &f->probing_parser_toclient_alproto_masks;
if (pp_port == NULL) {
if (pp_port_dp != NULL) {
SCLogDebug("toclient - Probing parser found for destination port %"PRIu16, f->dp);
/* found based on destination port, so use dp registration */
pe1 = pp_port_dp->dp;
} else {
SCLogDebug("toclient - No probing parser registered for dest port %"PRIu16,
f->dp);
}
/* dp not found, lets try source port then */
pp_port = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp);
if (pp_port == NULL) {
SCLogDebug("toclient - No probing parser registered for source port %"PRIu16,
f->sp);
pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp);
if (pp_port_sp != NULL) {
SCLogDebug("toclient - Probing parser found for source port %"PRIu16, f->sp);
FLOW_SET_PP_DONE(f, direction);
goto end;
}
pe2 = pp_port_sp->sp;
} else {
SCLogDebug("toclient - No probing parser registered for source port %"PRIu16,
f->sp);
}
pe = pp_port->dp;
}
if (pe1 == NULL && pe2 == NULL) {
SCLogDebug("%s - No probing parsers found for either port",
(direction & STREAM_TOSERVER) ? "toserver":"toclient");
FLOW_SET_PP_DONE(f, direction);
goto end;
}
/* run the parser(s) */
pe = pe1;
while (pe != NULL) {
if ((buflen < pe->min_depth) ||
(alproto_masks[0] & pe->alproto_mask)) {
@ -380,21 +402,47 @@ static AppProto AppLayerProtoDetectPPGetProto(Flow *f,
}
pe = pe->next;
}
pe = pe2;
while (pe != NULL) {
if ((buflen < pe->min_depth) ||
(alproto_masks[0] & pe->alproto_mask)) {
pe = pe->next;
continue;
}
if (direction & STREAM_TOSERVER) {
if (alproto_masks[0] == pp_port->toserver_alproto_mask) {
FLOW_SET_PP_DONE(f, direction);
alproto = pe->ProbingParser(buf, buflen, NULL);
if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED)
goto end;
if (alproto == ALPROTO_FAILED ||
(pe->max_depth != 0 && buflen > pe->max_depth)) {
alproto_masks[0] |= pe->alproto_mask;
}
pe = pe->next;
}
/* get the mask we need for this direction */
if (pp_port_dp && pp_port_sp)
mask = pp_port_dp->toserver_alproto_mask|pp_port_sp->toclient_alproto_mask;
else if (pp_port_dp)
mask = pp_port_dp->toserver_alproto_mask;
else if (pp_port_sp)
mask = pp_port_sp->toclient_alproto_mask;
else
mask = 0;
if (alproto_masks[0] == mask) {
FLOW_SET_PP_DONE(f, direction);
SCLogDebug("%s, mask is now %08x, needed %08x, so done",
(direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0], mask);
} else {
if (alproto_masks[0] == pp_port->toclient_alproto_mask) {
FLOW_SET_PP_DONE(f, direction);
goto end;
}
SCLogDebug("%s, mask is now %08x, need %08x",
(direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0], mask);
}
end:
SCReturnCT(alproto, "AppProto");
SCLogDebug("%s, mask is now %08x",
(direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0]);
SCReturnUInt(alproto);
}
/***** Static Internal Calls: PP registration *****/

Loading…
Cancel
Save