Backed out changeset 3c57c2281087
[prosody.git] / util / ip.lua
index 20ea3dd70594e4914116e15e1e8424b5bbd7a96d..62649c9b8567d6afe1aacc85d0aa91b7948245db 100644 (file)
@@ -14,8 +14,10 @@ local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011
 local function new_ip(ipStr, proto)
        if not proto then
                local sep = ipStr:match("^%x+(.)");
-               if sep == ":" then proto = "IPv6"
-               elseif sep == "." then proto = "IPv4"
+               if sep == ":" or (not(sep) and ipStr:sub(1,1) == ":") then
+                       proto = "IPv6"
+               elseif sep == "." then
+                       proto = "IPv4"
                end
                if not proto then
                        return nil, "invalid address";
@@ -215,5 +217,28 @@ function ip_methods:private()
        return private;
 end
 
+local function parse_cidr(cidr)
+       local bits;
+       local ip_len = cidr:find("/", 1, true);
+       if ip_len then
+               bits = tonumber(cidr:sub(ip_len+1, -1));
+               cidr = cidr:sub(1, ip_len-1);
+       end
+       return new_ip(cidr), bits;
+end
+
+local function match(ipA, ipB, bits)
+       local common_bits = commonPrefixLength(ipA, ipB);
+       if not bits then
+               return ipA == ipB;
+       end
+       if bits and ipB.proto == "IPv4" then
+               common_bits = common_bits - 96; -- v6 mapped addresses always share these bits
+       end
+       return common_bits >= bits;
+end
+
 return {new_ip = new_ip,
-       commonPrefixLength = commonPrefixLength};
+       commonPrefixLength = commonPrefixLength,
+       parse_cidr = parse_cidr,
+       match=match};