]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
decode-ipv4: implement extended security option
authorSascha Steinbiss <satta@debian.org>
Thu, 22 Sep 2022 13:10:47 +0000 (15:10 +0200)
committerVictor Julien <vjulien@oisf.net>
Thu, 29 Sep 2022 09:24:40 +0000 (11:24 +0200)
IP option 0x85 (extended security) is mentioned in the
documentation for the ipopts keyword but was not implemented.

src/decode-ipv4.c
src/decode-ipv4.h
src/detect-ipopts.c

index e472ca281b5943d5f4a52bd020b0c1776f331fd7..71c41d5a96a26fe8a99f99d0184e8cda7978133a 100644 (file)
@@ -66,6 +66,7 @@ static int IPV4OptValidateGeneric(Packet *p, const IPV4Opt *o)
             break;
         /* See: RFC 1108 */
         case IPV4_OPT_SEC:
+        case IPV4_OPT_ESEC:
             if (o->len != IPV4_OPT_SEC_LEN) {
                 ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN);
                 return -1;
@@ -290,6 +291,7 @@ typedef struct IPV4Options_ {
     IPV4Opt o_ts;
     IPV4Opt o_sec;
     IPV4Opt o_lsrr;
+    IPV4Opt o_esec;
     IPV4Opt o_cipso;
     IPV4Opt o_sid;
     IPV4Opt o_ssrr;
@@ -415,6 +417,15 @@ static int DecodeIPV4Options(Packet *p, const uint8_t *pkt, uint16_t len, IPV4Op
                         p->ip4vars.opts_set |= IPV4_OPT_FLAG_LSRR;
                     }
                     break;
+                case IPV4_OPT_ESEC:
+                    if (opts->o_esec.type != 0) {
+                        ENGINE_SET_EVENT(p, IPV4_OPT_DUPLICATE);
+                        /* Warn - we can keep going */
+                    } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
+                        opts->o_esec = opt;
+                        p->ip4vars.opts_set |= IPV4_OPT_FLAG_ESEC;
+                    }
+                    break;
                 case IPV4_OPT_CIPSO:
                     if (opts->o_cipso.type != 0) {
                         ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE);
@@ -912,6 +923,40 @@ static int DecodeIPV4OptionsSECTest02(void)
     PASS;
 }
 
+/** \test IPV4 with ESEC option. */
+static int DecodeIPV4OptionsESECTest01(void)
+{
+    uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+    Packet *p = PacketGetFromAlloc();
+    FAIL_IF(unlikely(p == NULL));
+
+    IPV4Options opts;
+    memset(&opts, 0x00, sizeof(opts));
+    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
+    FAIL_IF(p->flags & PKT_IS_INVALID);
+    FAIL_IF(opts.o_esec.type != IPV4_OPT_ESEC);
+    SCFree(p);
+    PASS;
+}
+
+/** \test IPV4 with ESEC option (invalid length). */
+static int DecodeIPV4OptionsESECTest02(void)
+{
+    uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x02, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+    Packet *p = PacketGetFromAlloc();
+    FAIL_IF(unlikely(p == NULL));
+
+    IPV4Options opts;
+    memset(&opts, 0x00, sizeof(opts));
+    DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
+    FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
+    FAIL_IF(opts.o_esec.type != 0);
+    SCFree(p);
+    PASS;
+}
+
 /** \test IPV4 with LSRR option. */
 static int DecodeIPV4OptionsLSRRTest01(void)
 {
@@ -1665,6 +1710,8 @@ void DecodeIPV4RegisterTests(void)
     UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04);
     UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01);
     UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02);
+    UtRegisterTest("DecodeIPV4OptionsESECTest01", DecodeIPV4OptionsESECTest01);
+    UtRegisterTest("DecodeIPV4OptionsESECTest02", DecodeIPV4OptionsESECTest02);
     UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01);
     UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02);
     UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03);
index 0da5ab5b8ec870f64daf19ac24019ec772e3a0b0..3b20eb8fc7d06577975f7574d471a26d182ccd60 100644 (file)
@@ -37,6 +37,7 @@
 #define IPV4_OPT_TS               0x44  /**< Option: Timestamp */
 #define IPV4_OPT_SEC              0x82  /**< Option: Security */
 #define IPV4_OPT_LSRR             0x83  /**< Option: Loose Source Route */
+#define IPV4_OPT_ESEC             0x85  /**< Option: Extended Security */
 #define IPV4_OPT_CIPSO            0x86  /**< Option: Commercial IP Security */
 #define IPV4_OPT_SID              0x88  /**< Option: Stream Identifier */
 #define IPV4_OPT_SSRR             0x89  /**< Option: Strict Source Route */
@@ -165,6 +166,7 @@ enum IPV4OptionFlags {
     IPV4_OPT_FLAG_SEC,
     IPV4_OPT_FLAG_CIPSO,
     IPV4_OPT_FLAG_RTRALT,
+    IPV4_OPT_FLAG_ESEC,
 };
 
 /* helper structure with parsed ipv4 info */
index dac1d24e15528fa19d6069cf013ec187bcc3bf44..944e1b16d2a8b1ea0fbfe11c0de6776bbfe1d446 100644 (file)
@@ -76,15 +76,46 @@ struct DetectIpOpts_ {
     const char *ipopt_name;   /**< ip option name */
     uint16_t code;   /**< ip option flag value */
 } ipopts[] = {
-    { "rr", IPV4_OPT_FLAG_RR, },
-    { "lsrr", IPV4_OPT_FLAG_LSRR, },
-    { "eol", IPV4_OPT_FLAG_EOL, },
-    { "nop", IPV4_OPT_FLAG_NOP, },
-    { "ts", IPV4_OPT_FLAG_TS, },
-    { "sec", IPV4_OPT_FLAG_SEC, },
-    { "ssrr", IPV4_OPT_FLAG_SSRR, },
-    { "satid", IPV4_OPT_FLAG_SID, },
-    { "any", 0xffff, },
+    {
+            "rr",
+            IPV4_OPT_FLAG_RR,
+    },
+    {
+            "lsrr",
+            IPV4_OPT_FLAG_LSRR,
+    },
+    {
+            "eol",
+            IPV4_OPT_FLAG_EOL,
+    },
+    {
+            "nop",
+            IPV4_OPT_FLAG_NOP,
+    },
+    {
+            "ts",
+            IPV4_OPT_FLAG_TS,
+    },
+    {
+            "sec",
+            IPV4_OPT_FLAG_SEC,
+    },
+    {
+            "esec",
+            IPV4_OPT_FLAG_ESEC,
+    },
+    {
+            "ssrr",
+            IPV4_OPT_FLAG_SSRR,
+    },
+    {
+            "satid",
+            IPV4_OPT_FLAG_SID,
+    },
+    {
+            "any",
+            0xffff,
+    },
     { NULL, 0 },
 };