diff --git a/src/app-layer-dnp3.c b/src/app-layer-dnp3.c index 1edb463c75..5c04ea19fc 100644 --- a/src/app-layer-dnp3.c +++ b/src/app-layer-dnp3.c @@ -271,7 +271,17 @@ static uint16_t DNP3ProbingParser(Flow *f, uint8_t direction, const uint8_t *input, uint32_t len, uint8_t *rdir) { - DNP3LinkHeader *hdr = (DNP3LinkHeader *)input; + const DNP3LinkHeader *const hdr = (const DNP3LinkHeader *)input; + const bool toserver = (direction & STREAM_TOSERVER) != 0; + + /* May be a banner. */ + if (DNP3ContainsBanner(input, len)) { + SCLogDebug("Packet contains a DNP3 banner."); + if (toserver) { + *rdir = STREAM_TOCLIENT; + } + return ALPROTO_DNP3; + } /* Check that we have the minimum amount of bytes. */ if (len < sizeof(DNP3LinkHeader)) { @@ -279,12 +289,6 @@ static uint16_t DNP3ProbingParser(Flow *f, uint8_t direction, return ALPROTO_UNKNOWN; } - /* May be a banner. */ - if (DNP3ContainsBanner(input, len)) { - SCLogDebug("Packet contains a DNP3 banner."); - goto end; - } - /* Verify start value (from AN2013-004b). */ if (!DNP3CheckStartBytes(hdr)) { SCLogDebug("Invalid start bytes."); @@ -297,11 +301,9 @@ static uint16_t DNP3ProbingParser(Flow *f, uint8_t direction, return ALPROTO_FAILED; } -end: // Test compatibility between direction and dnp3.ctl.direction - if ((DNP3_LINK_DIR(hdr->control) != 0) ^ - ((direction & STREAM_TOCLIENT) != 0)) { - *rdir = 1; + if ((DNP3_LINK_DIR(hdr->control) != 0) != toserver) { + *rdir = toserver ? STREAM_TOCLIENT : STREAM_TOSERVER; } SCLogDebug("Detected DNP3."); return ALPROTO_DNP3; @@ -2077,7 +2079,9 @@ static int DNP3ProbingParserTest(void) /* Send a banner. */ char mybanner[] = "Welcome to DNP3 SCADA."; - FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, (uint8_t *)mybanner, sizeof(mybanner), &rdir) != ALPROTO_DNP3); + FAIL_IF(DNP3ProbingParser(NULL, STREAM_TOSERVER, (uint8_t *)mybanner, sizeof(mybanner) - 1, + &rdir) != ALPROTO_DNP3); + FAIL_IF(rdir != STREAM_TOCLIENT); PASS; }