diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
index 549d92040b9b1e95cbbc2eb583795dd582388f66..9ee54bd1c8629a5f6d244df5336722b7f5fae5c4 100644
--- a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
+++ b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php
@@ -152,7 +152,7 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource {
 			if(!is_array($entry['hint.cidr'])) continue;
 			
 			foreach ($entry['hint.cidr'] AS $hint_entry) {
-				if (SimpleSAML_Utilities::ipCIDRcheck($hint_entry, $ip)) {
+				if (SimpleSAML_Utils_Net::ipCIDRcheck($hint_entry, $ip)) {
 					if ($type === 'entityid') {
 						return $entry['entityid'];
 					} else {
diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php
index 44a9fbfd1ec612cbc22e287995ac0471460a2441..a79613c2989af1608ad6913c863e81bd477b3d90 100644
--- a/lib/SimpleSAML/Utilities.php
+++ b/lib/SimpleSAML/Utilities.php
@@ -506,6 +506,7 @@ class SimpleSAML_Utilities {
 
 	/**
 	 * Check whether an IP address is part of an CIDR.
+	 * @deprecated This method will be removed in version 2.0.
 	 */
 	static function ipCIDRcheck($cidr, $ip = null) {
 		if ($ip == null) $ip = $_SERVER['REMOTE_ADDR'];
diff --git a/lib/SimpleSAML/Utils/Net.php b/lib/SimpleSAML/Utils/Net.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1511091acedf7d9a6a7a3401c0500c43ba962ed
--- /dev/null
+++ b/lib/SimpleSAML/Utils/Net.php
@@ -0,0 +1,82 @@
+<?php
+
+
+/**
+ * Net-related utility classes.
+ *
+ * @package SimpleSAMLphp
+ */
+class SimpleSAML_Utils_Net
+{
+
+    /**
+     * Check whether an IP address is part of a CIDR.
+     *
+     * @param string $cidr The network CIDR address.
+     * @param string $ip The IP address to check. Optional. Current remote address will be used if none specified. Do
+     * not rely on default parameter if running behind load balancers.
+     *
+     * @return boolean True if the IP address belongs to the specified CIDR, false otherwise.
+     *
+     * @author Andreas Ă…kre Solberg, UNINETT AS <andreas.solberg@uninett.no>
+     * @author Olav Morken, UNINETT AS <olav.morken@uninett.no>
+     * @author Brook Schofield, TERENA
+     * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no>
+     */
+    static function ipCIDRcheck($cidr, $ip = null)
+    {
+        if ($ip == null) {
+            $ip = $_SERVER['REMOTE_ADDR'];
+        }
+        if (strpos($cidr, '/') == false) {
+            return false;
+        }
+
+        list ($net, $mask) = explode('/', $cidr);
+
+        if (strstr($ip, ':') || strstr($net, ':')) {
+            // Validate IPv6 with inet_pton, convert to hex with bin2hex
+            // then store as a long with hexdec
+
+            $ip_pack = inet_pton($ip);
+            $net_pack = inet_pton($net);
+
+            if ($ip_pack === false || $net_pack === false) {
+                // not valid IPv6 address (warning already issued)
+                return false;
+            }
+
+            $ip_ip = str_split(bin2hex($ip_pack), 8);
+            foreach ($ip_ip as &$value) {
+                $value = hexdec($value);
+            }
+
+            $ip_net = str_split(bin2hex($net_pack), 8);
+            foreach ($ip_net as &$value) {
+                $value = hexdec($value);
+            }
+        } else {
+            $ip_ip[0] = ip2long($ip);
+            $ip_net[0] = ip2long($net);
+        }
+
+        for ($i = 0; $mask > 0 && $i < sizeof($ip_ip); $i++) {
+            if ($mask > 32) {
+                $iteration_mask = 32;
+            } else {
+                $iteration_mask = $mask;
+            }
+            $mask -= 32;
+
+            $ip_mask = ~((1 << (32 - $iteration_mask)) - 1);
+
+            $ip_net_mask = $ip_net[$i] & $ip_mask;
+            $ip_ip_mask = $ip_ip[$i] & $ip_mask;
+
+            if ($ip_ip_mask != $ip_net_mask) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/modules/negotiate/lib/Auth/Source/Negotiate.php b/modules/negotiate/lib/Auth/Source/Negotiate.php
index a29a0c2fb49c2ae24ef25f9b7cd1befbda083e9e..e956a00edbced318a7efd43913c7ed97f3706276 100644
--- a/modules/negotiate/lib/Auth/Source/Negotiate.php
+++ b/modules/negotiate/lib/Auth/Source/Negotiate.php
@@ -186,7 +186,7 @@ class sspmod_negotiate_Auth_Source_Negotiate extends SimpleSAML_Auth_Source {
 			return TRUE;
 		$ip = $_SERVER['REMOTE_ADDR'];
 		foreach ($this->subnet as $cidr) {
-			$ret = SimpleSAML_Utilities::ipCIDRcheck($cidr);
+			$ret = SimpleSAML_Utils_Net::ipCIDRcheck($cidr);
 			if ($ret) {
 				SimpleSAML_Logger::debug('Negotiate: Client "'.$ip.'" matched subnet.');
 				return TRUE;
diff --git a/tests/Utils/Net.php b/tests/Utils/Net.php
new file mode 100644
index 0000000000000000000000000000000000000000..474811aff9c7d45e9212f1935b8fd6c8c0fd4dbb
--- /dev/null
+++ b/tests/Utils/Net.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Class Utils_Net
+ */
+
+class Utils_Net extends PHPUnit_Framework_TestCase
+{
+
+
+    /**
+     * Test the function that checks for IPs belonging to a CIDR.
+     */
+    public function testIpCIDRcheck()
+    {
+        // check CIDR w/o mask
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0', '127.0.0.1'));
+
+        // check wrong CIDR w/ mask
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.256/24', '127.0.0.1'));
+
+        // check wrong IP
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/24', '127.0.0'));
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.*'));
+
+        // check limits for standard classes
+        $this->assertEquals(true,  SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.0'));
+        $this->assertEquals(true,  SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.255'));
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/24', '127.0.0.256'));
+
+        $this->assertEquals(true,  SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/16', '127.0.0.0'));
+        $this->assertEquals(true,  SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/16', '127.0.255.255'));
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/16', '127.0.255.256'));
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/16', '127.0.256.255'));
+
+        // check limits for non-standard classes
+        $this->assertEquals(true,  SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/23', '127.0.0.0'));
+        $this->assertEquals(true,  SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/23', '127.0.1.255'));
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/23', '127.0.1.256'));
+        $this->assertEquals(false, SimpleSAML_Utils_Net::ipCIDRcheck('127.0.0.0/23', '127.0.2.0'));
+    }
+}
\ No newline at end of file