]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Don't alert on valid ICMP6 solicit/advert messages.
authorJason Ish <jason.ish@emulex.com>
Wed, 5 Feb 2014 23:27:42 +0000 (17:27 -0600)
committerVictor Julien <victor@inliniac.net>
Fri, 7 Feb 2014 16:11:20 +0000 (17:11 +0100)
Handles ND_ROUTER_SOLICIT, ND_ROUTER_ADVERT, ND_NEIGHBOUR_ADMIN,
ND_NEIGHBOUR_SOLICIT and ND_REDIRECT.  Don't set ICMPV6_UNKONWN_CODE
if code is the expected value of 0.

src/decode-icmpv6.c
src/decode-icmpv6.h

index bbd540c478b3f23c89649d02a4216f4364fbe538..660ad989cee1474a2c34b6a96d7b718011cd6f0f 100644 (file)
@@ -262,6 +262,22 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
                 full_hdr = 1;
             }
 
+            break;
+        case ND_ROUTER_SOLICIT:
+            SCLogDebug("ND_ROUTER_SOLICIT");
+        case ND_ROUTER_ADVERT:
+            SCLogDebug("ND_ROUTER_ADVERT");
+        case ND_NEIGHBOR_SOLICIT:
+            SCLogDebug("ND_NEIGHBOR_SOLICIT");
+        case ND_NEIGHBOR_ADVERT:
+            SCLogDebug("ND_NEIGHBOR_ADVERT");
+        case ND_REDIRECT:
+            SCLogDebug("ND_REDIRECT");
+
+            if (p->icmpv6h->code != 0) {
+                ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
+            }
+
             break;
         default:
             SCLogDebug("ICMPV6 Message type %" PRIu8 " not "
@@ -1108,6 +1124,426 @@ end:
     return retval;
 }
 
+static int ICMPV6RouterSolicitTestKnownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x85, 0x00, 0xbe, 0xb0, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6RouterSolicitTestUnknownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x85, 0x01, 0xbe, 0xaf, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is not set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6RouterAdvertTestKnownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x86, 0x00, 0xbd, 0xb0, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6RouterAdvertTestUnknownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x86, 0x01, 0xbd, 0xaf, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is not set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6NeighbourSolicitTestKnownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x87, 0x00, 0xbc, 0xb0, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6NeighbourSolicitTestUnknownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x87, 0x01, 0xbc, 0xaf, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is not set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6NeighbourAdvertTestKnownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x88, 0x00, 0xbb, 0xb0, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6NeighbourAdvertTestUnknownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x88, 0x01, 0xbb, 0xaf, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is not set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6RedirectTestKnownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x89, 0x00, 0xba, 0xb0, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
+static int ICMPV6RedirectTestUnknownCode(void)
+{
+    int retval = 0;
+
+    static uint8_t raw_ipv6[] = {
+        0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
+        0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
+        0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        0x89, 0x01, 0xba, 0xaf, 0x00, 0x00, 0x00, 0x00
+    };
+
+    Packet *p = SCMalloc(SIZE_OF_PACKET);
+    if (unlikely(p == NULL))
+        return 0;
+    IPV6Hdr ip6h;
+    ThreadVars tv;
+    DecodeThreadVars dtv;
+
+    memset(&tv, 0, sizeof(ThreadVars));
+    memset(p, 0, SIZE_OF_PACKET);
+    memset(&dtv, 0, sizeof(DecodeThreadVars));
+    memset(&ip6h, 0, sizeof(IPV6Hdr));
+
+    FlowInitConfig(FLOW_QUIET);
+    DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL);
+
+    if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) {
+        SCLogDebug("ICMPv6 Error: Unknown code event is not set");
+        retval = 0;
+        goto end;
+    }
+
+    retval = 1;
+end:
+    PACKET_RECYCLE(p);
+    FlowShutdown();
+    SCFree(p);
+    return retval;
+}
+
 #endif /* UNITTESTS */
 /**
  * \brief Registers ICMPV6 unit tests
@@ -1134,6 +1570,28 @@ void DecodeICMPV6RegisterTests(void)
     UtRegisterTest("ICMPV6EchoRepTest02 (Invalid)", ICMPV6EchoRepTest02, 1);
 
     UtRegisterTest("ICMPV6PayloadTest01", ICMPV6PayloadTest01, 1);
+
+    UtRegisterTest("ICMPV6RouterSolicitTestKnownCode",
+        ICMPV6RouterSolicitTestKnownCode, 1);
+    UtRegisterTest("ICMPV6RouterSolicitTestUnknownCode",
+        ICMPV6RouterSolicitTestUnknownCode, 1);
+    UtRegisterTest("ICMPV6RouterAdvertTestKnownCode",
+        ICMPV6RouterAdvertTestKnownCode, 1);
+    UtRegisterTest("ICMPV6RouterAdvertTestUnknownCode",
+        ICMPV6RouterAdvertTestUnknownCode, 1);
+
+    UtRegisterTest("ICMPV6NeighbourSolicitTestKnownCode",
+        ICMPV6NeighbourSolicitTestKnownCode, 1);
+    UtRegisterTest("ICMPV6NeighbourSolicitTestUnknownCode",
+        ICMPV6NeighbourSolicitTestUnknownCode, 1);
+    UtRegisterTest("ICMPV6NeighbourAdvertTestKnownCode",
+        ICMPV6NeighbourAdvertTestKnownCode, 1);
+    UtRegisterTest("ICMPV6NeighbourAdvertTestUnknownCode",
+        ICMPV6NeighbourAdvertTestUnknownCode, 1);
+
+    UtRegisterTest("ICMPV6RedirectTestKnownCode", ICMPV6RedirectTestKnownCode, 1);
+    UtRegisterTest("ICMPV6RedirectTestUnknownCode",
+        ICMPV6RedirectTestUnknownCode, 1);
 #endif /* UNITTESTS */
 }
 /**
index e5d429ab143efa5966285c897d5f652673041045..af97500607f88356b3570e686ae31c9fb3c300a5 100644 (file)
 #define MLD_LISTENER_REPORT         131
 #define MLD_LISTENER_REDUCTION      132
 
+#define ND_ROUTER_SOLICIT           133
+#define ND_ROUTER_ADVERT            134
+#define ND_NEIGHBOR_SOLICIT         135
+#define ND_NEIGHBOR_ADVERT          136
+#define ND_REDIRECT                 137
+
 /** Destination Unreachable Message (type=1) Code: */
 
 #define ICMP6_DST_UNREACH_NOROUTE       0 /* no route to destination */