diff --git a/src/decode-teredo.c b/src/decode-teredo.c index 4b8c648a16..6206311579 100644 --- a/src/decode-teredo.c +++ b/src/decode-teredo.c @@ -41,16 +41,18 @@ #include "detect-engine-port.h" #define TEREDO_ORIG_INDICATION_LENGTH 8 +#define TEREDO_MAX_PORTS 4 +#define TEREDO_UNSET_PORT -1 static bool g_teredo_enabled = true; -static int g_teredo_ports[4] = { -1, -1, -1, -1 }; -static int g_teredo_ports_cnt = 0; static bool g_teredo_ports_any = true; +static int g_teredo_ports_cnt = 0; +static int g_teredo_ports[TEREDO_MAX_PORTS] = { TEREDO_UNSET_PORT, TEREDO_UNSET_PORT, + TEREDO_UNSET_PORT, TEREDO_UNSET_PORT }; bool DecodeTeredoEnabledForPort(const uint16_t sp, const uint16_t dp) { - SCLogDebug("ports %u->%u ports %d %d %d %d", sp, dp, - g_teredo_ports[0], g_teredo_ports[1], + SCLogDebug("ports %u->%u ports %d %d %d %d", sp, dp, g_teredo_ports[0], g_teredo_ports[1], g_teredo_ports[2], g_teredo_ports[3]); if (g_teredo_enabled) { @@ -60,11 +62,10 @@ bool DecodeTeredoEnabledForPort(const uint16_t sp, const uint16_t dp) } for (int i = 0; i < g_teredo_ports_cnt; i++) { - if (g_teredo_ports[i] == -1) + if (g_teredo_ports[i] == TEREDO_UNSET_PORT) return false; const int port = g_teredo_ports[i]; - if (port == (const int)sp || - port == (const int)dp) + if (port == (const int)sp || port == (const int)dp) return true; } } @@ -86,13 +87,14 @@ static void DecodeTeredoConfigPorts(const char *pstr) g_teredo_ports_any = false; g_teredo_ports_cnt = 0; for (DetectPort *p = head; p != NULL; p = p->next) { - if (g_teredo_ports_cnt >= 4) { - SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY, - "only 4 Teredo ports can be defined"); + if (g_teredo_ports_cnt >= TEREDO_MAX_PORTS) { + SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY, "only %d Teredo ports can be defined", + TEREDO_MAX_PORTS); break; } g_teredo_ports[g_teredo_ports_cnt++] = (int)p->port; } + DetectPortCleanupList(NULL, head); } @@ -135,21 +137,17 @@ int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, * part before the IPv6 packet. In our case, we just want to get * over an ORIGIN indication. So we just make one offset if needed. */ if (start[0] == 0x0) { - switch (start[1]) { - /* origin indication: compatible with tunnel */ - case 0x0: - /* offset is coherent with len and presence of an IPv6 header */ - if (len >= TEREDO_ORIG_INDICATION_LENGTH + IPV6_HEADER_LEN) - start += TEREDO_ORIG_INDICATION_LENGTH; - else - return TM_ECODE_FAILED; - break; - /* authentication: negotiation not real tunnel */ - case 0x1: - return TM_ECODE_FAILED; - /* this case is not possible in Teredo: not that protocol */ - default: + /* origin indication: compatible with tunnel */ + if (start[1] == 0x0) { + /* offset is not coherent with len and presence of an IPv6 header */ + if (len < TEREDO_ORIG_INDICATION_LENGTH + IPV6_HEADER_LEN) return TM_ECODE_FAILED; + + start += TEREDO_ORIG_INDICATION_LENGTH; + + /* either authentication negotiation not real tunnel or invalid second byte */ + } else { + return TM_ECODE_FAILED; } }