From 9edfd0002bea4d591cb363be536c652ef3f16079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Sloth=20T=C3=B8nnesen?= Date: Sat, 20 Jul 2019 18:19:38 +0000 Subject: add inet:subnets() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Asbjørn Sloth Tønnesen --- README.rst | 19 +++++++++++++++++++ lua/inet/core.lua | 13 ++++++++++++- test/inet.lua | 5 +++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 3bbb9c4..799f602 100644 --- a/README.rst +++ b/README.rst @@ -83,6 +83,7 @@ Operator Description ``:hostmask()`` generate hostmask as an address ``:flip()`` flip the least significant network bit ``:bits()`` return the address bits in a table +``:subnets()`` return the amount of /n subnets ================= ====================================== @@ -397,6 +398,24 @@ Valid values for ``n`` are ``1``, ``2``, ``4``, ``8``, ``16`` or ``32``. { 2, 0, 0, 1, 0, 13, 11, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2 } + +``foo:subnets(n)`` +~~~~~~~~~~~~~~~~~~ + +:: + + inet('192.0.2.0/24'):subnets(26) -- returns 4 + inet('192.0.2.0/25'):subnets(26) -- returns 2 + inet('192.0.2.0/26'):subnets(26) -- returns 1 + inet('192.0.2.0/27'):subnets(26) -- returns 0.5 + inet('192.0.2.0/28'):subnets(26) -- returns 0.25 + + inet('2001:db8::/48'):subnets(56) -- returns 256 + inet('2001:db8::/56'):subnets(64) -- returns 256 + inet('2001:db8::/48'):subnets(64) -- returns 65536 + inet('2001:db8::/64'):subnets(56) -- returns 0.00390625 + + Sets ---- diff --git a/lua/inet/core.lua b/lua/inet/core.lua index f1c7c49..15dd0f9 100644 --- a/lua/inet/core.lua +++ b/lua/inet/core.lua @@ -6,6 +6,7 @@ local format = string.format local floor = math.floor local min = math.min local max = math.max +local pow = math.pow local insert = table.insert local lshift = bit32.lshift @@ -55,6 +56,16 @@ end inet4.__len = inet.__len inet6.__len = inet.__len +function inet:subnets(n) + if type(n) ~= 'number' then return nil, 'n must be a number' end + local hostmask = is_inet6(self) and 128 or 32 + if n < 0 or n > hostmask then return nil, 'invalid mask given' end + local mask = self.mask + local bits = n - mask + local subnets = pow(2, bits) + return subnets +end + function inet:family() local mt = assert(getmetatable(self)) return assert(mt2fam[mt]) @@ -329,7 +340,7 @@ function inet4:__sub(n) end function inet4:__mul(n) - local new = self.bip + (n * math.pow(2, 32 - self.mask)) + local new = self.bip + (n * pow(2, 32 - self.mask)) return new_inet4(new, self.mask) end diff --git a/test/inet.lua b/test/inet.lua index b974179..f2968bd 100644 --- a/test/inet.lua +++ b/test/inet.lua @@ -305,6 +305,11 @@ local function misc() assert(inet('2001:db8::42/64'):bits(0) == nil) assert(inet('2001:db8::42/64'):bits(42) == nil) assert(inet('2001:db8::42/64'):bits(64) == nil) + + assert(inet('192.0.2.24'):subnets(-1) == nil) + assert(inet('192.0.2.24'):subnets(33) == nil) + assert(inet('2001:db8::42/64'):subnets(-1) == nil) + assert(inet('2001:db8::42/64'):subnets(129) == nil) end local t = test.new() -- cgit v1.2.1