aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.rst28
-rw-r--r--lua/inet/core.lua33
-rw-r--r--test/inet.lua9
3 files changed, 70 insertions, 0 deletions
diff --git a/README.rst b/README.rst
index 5698887..3bbb9c4 100644
--- a/README.rst
+++ b/README.rst
@@ -82,6 +82,7 @@ Operator Description
``:netmask()`` generate netmask as an address
``:hostmask()`` generate hostmask as an address
``:flip()`` flip the least significant network bit
+``:bits()`` return the address bits in a table
================= ======================================
@@ -369,6 +370,33 @@ Like ``tostring(foo)``, but never uses mixed notation.
inet('::ffff:192.0.2.24'):ipstring() -- returns '::ffff:192.0.2.24'
inet('::ffff:192.0.2.24'):ipstring6() -- returns '::ffff:c000:218'
+
+``foo:bits(n)``
+~~~~~~~~~~~~~~~
+
+Return the IP as a table with elements of ``n`` bits each.
+
+Valid values for ``n`` are ``1``, ``2``, ``4``, ``8``, ``16`` or ``32``.
+
+::
+
+ inet('192.0.2.24'):bits(32) -- returns { 3221226008 }
+ inet('192.0.2.24'):bits(16) -- returns { 49152, 536 }
+ inet('192.0.2.24'):bits(8) -- returns { 192, 0, 2, 24 }
+ inet('192.0.2.24'):bits(4) -- returns { 12, 0, 0, 0, 0, 2, 1, 8 }
+ inet('192.0.2.24'):bits(1) -- returns
+ { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0 }
+
+ inet('2001:db8::42/64'):bits(32) -- returns { 536939960, 0, 0, 66 }
+ inet('::ffff:192.0.2.24'):bits(32) -- returns { 0, 0, 65535, 3221226008 }
+ inet('2001:db8::42/64'):bits(16) -- returns { 8193, 3512, 0, 0, 0, 0, 0, 66 }
+ inet('2001:db8::42/64'):bits(8) -- returns
+ { 32, 1, 13, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66 }
+ inet('2001:db8::42/64'):bits(4) -- returns
+ { 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 }
+
Sets
----
diff --git a/lua/inet/core.lua b/lua/inet/core.lua
index a91dacd..f1c7c49 100644
--- a/lua/inet/core.lua
+++ b/lua/inet/core.lua
@@ -6,10 +6,12 @@ local format = string.format
local floor = math.floor
local min = math.min
local max = math.max
+local insert = table.insert
local lshift = bit32.lshift
local rshift = bit32.rshift
local band = bit32.band
+local extract = bit32.extract
local replace = bit32.replace
local bxor = bit32.bxor
@@ -403,6 +405,17 @@ function inet4:flip()
return new_inet4(bxor(self.bip, flipbit), mask)
end
+function inet4:bits(n)
+ if type(n) ~= 'number' then return nil, 'n must be a number' end
+ if n < 1 or n > 32 or 32 % n ~= 0 then return nil, 'invalid value for n' end
+ local t = {}
+ local bip = self.bip
+ for i=32-n,0,-n do
+ insert(t, extract(bip, i, n))
+ end
+ return t
+end
+
-- each ipv6 address is stored as eight pieces
-- 1111:2222:3333:4444:5555:6666:7777:8888
-- in the table pcs.
@@ -789,6 +802,26 @@ function inet6:__mul(n)
return new:balance()
end
+function inet6:bits(n)
+ if type(n) ~= 'number' then return nil, 'n must be a number' end
+ if n < 1 or n > 32 or 128 % n ~= 0 then return nil, 'invalid value for n' end
+ local t = {}
+ local pcs = self.pcs
+ if n == 32 then
+ for i=1,8,2 do
+ insert(t, lshift(pcs[i], 16) + pcs[i+1])
+ end
+ else
+ for i=1,8 do
+ local p = pcs[i]
+ for j=16-n,0,-n do
+ insert(t, extract(p, j, n))
+ end
+ end
+ end
+ return t
+end
+
local M = {}
function M.set_mixed_networks(mixed_set)
diff --git a/test/inet.lua b/test/inet.lua
index dd90fef..b974179 100644
--- a/test/inet.lua
+++ b/test/inet.lua
@@ -296,6 +296,15 @@ local function misc()
assert(inet('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff') + 1 == nil)
assert(inet('0.0.0.0/24') * -1 == nil)
assert(inet('255.255.255.0/24') * 1 == nil)
+
+ assert(inet('192.0.2.24'):bits(-1) == nil)
+ assert(inet('192.0.2.24'):bits(0) == nil)
+ assert(inet('192.0.2.24'):bits(3) == nil)
+ assert(inet('192.0.2.24'):bits(33) == nil)
+ assert(inet('2001:db8::42/64'):bits(-1) == nil)
+ 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)
end
local t = test.new()