]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
decode/teredo: Modified/refactored Teredo logic
authorAli Jad Khalil <jadkhal@amazon.com>
Sat, 2 May 2020 21:04:07 +0000 (21:04 +0000)
committerVictor Julien <victor@inliniac.net>
Fri, 4 Sep 2020 11:13:37 +0000 (13:13 +0200)
This is just a slight refactor to make analagous decoding/encapsulation
schemes - Geneve, Teredo, and VXLAN - be implemented as similarly as
possible.

src/decode-teredo.c

index 4b8c648a16d5b6763897445ca0cbbf70d49b46a8..6206311579b5f018354243e61ba43afbf6b51faa 100644 (file)
 #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;
         }
     }