elseif proto ~= "IPv4" and proto ~= "IPv6" then
return nil, "invalid protocol";
end
+ local zone;
+ if proto == "IPv6" and ipStr:find('%', 1, true) then
+ ipStr, zone = ipStr:match("^(.-)%%(.*)");
+ end
if proto == "IPv6" and ipStr:find('.', 1, true) then
local changed;
ipStr, changed = ipStr:gsub(":(%d+)%.(%d+)%.(%d+)%.(%d+)$", function(a,b,c,d)
if changed ~= 1 then return nil, "invalid-address"; end
end
- return setmetatable({ addr = ipStr, proto = proto }, ip_mt);
+ return setmetatable({ addr = ipStr, proto = proto, zone = zone }, ip_mt);
end
local function toBits(ip)
if not ip:match(":$") then fields[#fields] = nil; end
for i, field in ipairs(fields) do
if field:len() == 0 and i ~= 1 and i ~= #fields then
- for i = 1, 16 * (9 - #fields) do
+ for _ = 1, 16 * (9 - #fields) do
result = result .. "0";
end
else
- for i = 1, 4 - field:len() do
+ for _ = 1, 4 - field:len() do
result = result .. "0000";
end
- for i = 1, field:len() do
- result = result .. hex2bits[field:sub(i,i)];
+ for j = 1, field:len() do
+ result = result .. hex2bits[field:sub(j, j)];
end
end
end
if ip:match("^[0:]*1$") then
return 0x2;
-- Link-local unicast:
- elseif ip:match("^[Ff][Ee][89ABab]") then
+ elseif ip:match("^[Ff][Ee][89ABab]") then
return 0x2;
-- Site-local unicast:
elseif ip:match("^[Ff][Ee][CcDdEeFf]") then
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;
+ return common_bits >= (bits or 128);
end
return {new_ip = new_ip,