local n=require
local c=pcall
local f=error
local e=n("tch.posix")local i=n("bit")local t=e.AF_INET
local r=e.AF_INET6
local l=e.inet_pton
local o=e.inet_ntop
local h,I=string.match,string.format
local a,s=tonumber,type
local v=math.floor
local n={}function n.isValidIPv4(n)local n,e=l(t,n)if n then
return true
end
return nil,e
end
function n.isValidIPv6(n)local n,e=l(r,n)if n then
return true
end
return nil,e
end
local b={IPv4=t,IPv6=r,}local u={[t]="IPv4",[r]="IPv6"}local function d(i,o)local l
local n
if not o then
n=e.inet_pton(t,i)if n then
l=t
else
n=e.inet_pton(r,i)if n then
l=r
else
return nil,"not a valid IP address (v4 nor v6)"end
end
else
l=b[o]if not l then
return nil,"invalid address family, must be IPv4 or IPv6"end
local t
n,t=e.inet_pton(l,i)if not n then
return nil,t
end
end
return n,l
end
function n.isValidIP(n)local e,n=d(n)if not e then
return nil,n
end
return u[n]end
function n.normalizeIP(e,n)local e,n=d(e,n)if not e or not o then
return nil,n
end
return o(n,e),u[n]end
function n.ipIsZero(e,n)local n,e=d(e,n)if not n then
return f(e)end
for e=1,#n do
if n:byte(e)~=0 then
return false
end
end
return true
end
function n.hexIPv4ToString(n)if s(n)~="string"then
return nil,"argument not a string"end
local n,e,l,t=h(n,"^%s*(%x%x)(%x%x)(%x%x)(%x%x)%s*$")if not n then
return nil,"string is not a valid IPv4 address in hexadecimal notation"end
n,e,l,t=a(n,16),a(e,16),a(l,16),a(t,16)return I("%d.%d.%d.%d",n,e,l,t)end
function n.isValidGlobalUnicastv6Address(n)local n=l(r,n)if n then
if i.band(n:byte(1),224)==32 then
return true
end
end
return nil,"Invalid Global Unicast Address"end
function n.ipv4ToNumber(n)if n then
local o,r,t=c(l,t,n)if o and r then
if t then
return t
else
local n=l and l(e.AF_INET,n)or nil
if not n then
return nil
end
local l,e,t,n=n:byte(1,4)return i.tobit((l*16777216)+(e*65536)+(t*256)+n)end
else
return nil,"invalid input data"end
end
end
local a=n.ipv4ToNumber
function n.numberToIpv4(n)local t,e=c(o,t,n)if not o then
return nil,"posix inet_ntop not supported"end
if t then
if e then
return e
else
local e=i.band
local t=i.rshift
return e(t(n,24),255).."."..e(t(n,16),255).."."..e(t(n,8),255).."."..e(n,255)end
end
return nil,"invalid data"end
local d=n.numberToIpv4
function n.validateIPv4Netmask(n)local t=a(n)if not t then
return nil,"String is not an IPv4 address."end
local n=0
local e=0
for l=0,31 do
local l=i.lshift(1,l)local t=i.band(t,l)if t==0 then
if e~=0 then
return nil,"Invalid subnet."end
else
if e==0 then
e=1
end
n=n+1
end
end
if(n<0)or(n>30)then
return nil,"Invalid subnet."end
return true,32-n
end
function n.getPossibleHostsInIPv4Subnet(e)local e,n=n.validateIPv4Netmask(e)if not e then
return nil,n
end
return(2^n)-2
end
local e
local l
local function i(n)if n and 1<=n and n<=32 then
return(2^n-1)*(2^(32-n))end
end
local function r()if e then
return
end
e={}l={}for n=1,32 do
local r=i(n)e[n]=r
local e=o(t,r)l[e]=n
end
end
function n.netmaskToNumber(n)r()return e[n]end
function n.mask2netmask(n)r()local n=l[n]if n and n<31 then
return n
end
end
function n.ipv4BroadcastAddr(e,n)local e=a(e)if not e or n<1 or 32<n then
return nil,"invalid input data"end
local n=2^(32-n)return d(v(e/n)*n+(n-1))end
return n