]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ipv6: add string validation function
authorVictor Julien <victor@inliniac.net>
Sun, 26 Nov 2017 10:17:57 +0000 (11:17 +0100)
committerVictor Julien <victor@inliniac.net>
Wed, 20 Dec 2017 15:23:31 +0000 (16:23 +0100)
src/util-decode-mime.c
src/util-ip.c
src/util-ip.h

index 2f5cbdfc1c14aaac2d69d8de3047c1401730319f..704533a70cfcafc6a1f8d15ae3a89441c26dd24b 100644 (file)
@@ -949,37 +949,11 @@ static int IsIpv6Host(const uint8_t *urlhost, uint32_t len)
     char tempIp[MAX_IP6_CHARS + 1];
 
     /* Cut off at '/'  */
-    int block_size = 0;
-    int sep = 0;
-    bool colon_seen = false;
     uint32_t i = 0;
     for (i = 0; i < len && urlhost[i] != 0; i++) {
         if (urlhost[i] == '/') {
             break;
         }
-        if (!(urlhost[i] == '.' || urlhost[i] == ':' ||
-            isxdigit(urlhost[i])))
-            return 0;
-
-        if (urlhost[i] == ':') {
-            block_size = 0;
-            colon_seen = true;
-            sep++;
-        } else if (urlhost[i] == '.') {
-            block_size = 0;
-            sep++;
-        } else {
-            if (block_size == 4)
-                return 0;
-            block_size++;
-        }
-    }
-
-    if (!colon_seen)
-        return 0;
-    if (sep > 7) {
-        SCLogDebug("too many seps %d", sep);
-        return 0;
     }
 
     /* Too many chars */
@@ -991,6 +965,9 @@ static int IsIpv6Host(const uint8_t *urlhost, uint32_t len)
     memcpy(tempIp, urlhost, i);
     tempIp[i] = '\0';
 
+    if (!IPv6AddressStringIsValid(tempIp))
+        return 0;
+
     return inet_pton(AF_INET6, tempIp, &in6);
 }
 
index 908a17d9180a75f11a065248a8a951e1d303b9f5..7b568986fb61553a6e935cc797c49fe179ab4c4f 100644 (file)
@@ -74,6 +74,45 @@ bool IPv4AddressStringIsValid(const char *str)
     return true;
 }
 
+/** \brief determine if a string is a valid ipv6 address
+ *  \retval bool is addr valid?
+ */
+bool IPv6AddressStringIsValid(const char *str)
+{
+    int block_size = 0;
+    int sep = 0;
+    bool colon_seen = false;
+
+    uint32_t len = strlen(str);
+    uint32_t i = 0;
+    for (i = 0; i < len && str[i] != 0; i++) {
+        if (!(str[i] == '.' || str[i] == ':' ||
+            isxdigit(str[i])))
+            return false;
+
+        if (str[i] == ':') {
+            block_size = 0;
+            colon_seen = true;
+            sep++;
+        } else if (str[i] == '.') {
+            block_size = false;
+            sep++;
+        } else {
+            if (block_size == 4)
+                return false;
+            block_size++;
+        }
+    }
+
+    if (!colon_seen)
+        return false;
+    if (sep > 7) {
+        SCLogDebug("too many seps %d", sep);
+        return false;
+    }
+    return true;
+}
+
 /**
  * \brief Validates an IPV4 address and returns the network endian arranged
  *        version of the IPV4 address
@@ -120,6 +159,9 @@ struct in6_addr *ValidateIPV6Address(const char *addr_str)
 {
     struct in6_addr *addr = NULL;
 
+    if (!IPv6AddressStringIsValid(addr_str))
+        return NULL;
+
     if ( (addr = SCMalloc(sizeof(struct in6_addr))) == NULL) {
         SCLogError(SC_ERR_FATAL, "Fatal error encountered in ValidateIPV6Address. Exiting...");
         exit(EXIT_FAILURE);
index f92369ccb4e30edb478c80163af4b1cddc454df5..d0bcc884f1f2c3a1b0e4d1a73870d917e53705cd 100644 (file)
@@ -26,6 +26,7 @@
 #define __UTIL_IP_H__
 
 bool IPv4AddressStringIsValid(const char *str);
+bool IPv6AddressStringIsValid(const char *str);
 struct in_addr *ValidateIPV4Address(const char *);
 struct in6_addr *ValidateIPV6Address(const char *);
 void MaskIPNetblock(uint8_t *, int, int);