Anonymous user
Module:IP: Difference between revisions
From the Croc Wiki, the Croc encyclopedia
Jump to navigationJump to search
try original format again
(try different format with underscores instead of private data) |
(try original format again) |
||
Line 165:
end
local function ipv4Address(data, ipStr)
-- If ipStr is a valid IPv4 string, store its parts in data and
-- return true. Otherwise, return false.
-- This representation is for compatibility with IPv6 addresses.
local octets = collection()
local s = ipStr:match('^%s*(.-)%s*$') .. '.'
for item in s:gmatch('(.-)%.') do
octets:add(item)
end
if octets.n == 4 then
for i, s in ipairs(octets) do
if s:match('^%d+$') then
local num = tonumber(s)
if 0 <= num and num <= 255 then
if num > 0 and s:match('^0') then
-- A redundant leading zero is for an IP in octal.
return false
end
octets[i] = num
else
return false
end
else
return false
end
end
data.parts = collection()
for i = 1, 3, 2 do
data.parts:add(octets[i] * 256 + octets[i+1])
end
return true
end
return false
end
else
local num = tonumber('0x' .. s)
if num and 0 <= num and num <= 65535 then
parts[i] = num
else
return false
end
end
end
data.parts = parts
return true
end
return false
end
--------------------------------------------------------------------------------
-- Represents a single IPv4 or IPv6 address.
--------------------------------------------------------------------------------
local IPAddress = {}
do
local dataKey = {} -- A unique key to access objects' internal data.
-- Static private methods
local function ipEquals(ip1, ip2)
local
local rhs = ip2[dataKey].parts
if lhs.n == rhs.n then
for i = 1, lhs.n do
Line 312 ⟶ 256:
end
local function
local lhs =
local rhs =
if lhs.n == rhs.n then
for i = 1, lhs.n do
Line 326 ⟶ 270:
end
-- Constructor
function IPAddress.new(ip)
checkType('IPAddress.new', 1, ip, 'string')
-- Set up structure
local obj = {}
local data = {}
-- Set initial values
if not (ipv4Address(data, ip) or ipv6Address(data, ip)) then
error('invalid IP', 2)
end
data.version = data.parts.n == 2 and V4 or V6
-- Public methods
function obj:getIP()
return ipString(data.parts)
end
function obj:getVersion()
return data.version
end
function obj:getHighestIP(bitLength)
return IPAddress.new(uniqueId, setHostBits(data.parts, bitLength))
end
function obj:getPrefix(bitLength)
return IPAddress.new(uniqueId, copyPrefix(data.parts, bitLength))
end
function obj:isIPv4()
return data.version == V4
end
function obj:isIPv6()
return data.version == V6
end
function obj:isInSubnet(subnet)
-- TODO Consider alternative of checking:
-- (ipFirst <= self and self <= ipLast)
if self:getVersion() == subnet:getVersion() then
local prefix = self:getPrefix(subnet:getBitLength())
return prefix == subnet:getPrefix()
end
return false
end
function obj:getNextIP()
return IPAddress.new(uniqueId, copyChanged(data.parts))
end
function obj:getPreviousIP()
return IPAddress.new(uniqueId, copyChanged(data.parts, true))
end
-- Metamethods
return setmetatable(obj, {
__eq = ipEquals,
__lt = ipLessThan,
__index = function (self, key)
if key == dataKey then
return data
end
end,
__concat = function (self, obj)
return tostring(self) .. tostring(obj)
end,
__tostring = function (self)
return ipString(self:getIPParts())
end,
})
end
end
|