diff options
-rw-r--r-- | README.rst | 6 | ||||
-rw-r--r-- | lua/inet/core.lua | 28 |
2 files changed, 33 insertions, 1 deletions
@@ -79,7 +79,7 @@ Operator Description ``tostring(net)`` convert to network ``:ipstring()`` ip as string without prefix ``:cidrstring()`` format CIDR notation -``:netmask()`` generate netmask as address +``:netmask()`` generate netmask as an address ``:flip()`` flip the least significant network bit ================= ====================================== @@ -234,6 +234,10 @@ Build an IP address mask with the netmask of ``foo``. :: inet('192.0.2.0/24'):netmask() -- returns inet('255.255.255.0') + inet('2001:db8::/52'):netmask() -- returns inet('ffff:ffff:ffff:f000::') + inet('2001:db8::/56'):netmask() -- returns inet('ffff:ffff:ffff:ff00::') + inet('2001:db8::/64'):netmask() -- returns inet('ffff:ffff:ffff:ffff::') + ``foo:flip()`` ~~~~~~~~~~~~~~ diff --git a/lua/inet/core.lua b/lua/inet/core.lua index 9848e52..0b062e7 100644 --- a/lua/inet/core.lua +++ b/lua/inet/core.lua @@ -3,6 +3,9 @@ local bit32 = require 'bit32' local common = require 'inet.common' local format = string.format +local floor = math.floor +local min = math.min +local max = math.max local lshift = bit32.lshift local rshift = bit32.rshift @@ -688,6 +691,31 @@ function inet6:network() return new_inet6(newpcs, netbits) end +local function build_inet6_mask(z1, o1, z2) + assert(z1 + o1 + z2 == 128) + local pcs = { 0, 0, 0, 0, 0, 0, 0, 0 } + local b, l = z1, o1 + if l > 0 then + local e = b + l - 1 + local bpcs = floor(b / 16) + 1 + local epcs = floor(e / 16) + 1 + for j=bpcs,epcs do + local o = (j-1) * 16 + local bo = max(0,b-o) + local width = min(15,e-o)+1 - bo + local fbit = 16 - width - bo + local v = replace(pcs[j], 0xffff, fbit, width) + pcs[j] = v + end + end + return new_inet6(pcs) +end + +function inet6:netmask() + local mask = self.mask + return build_inet6_mask(0, mask, 128 - mask) +end + function inet6:flip() -- find twin by flipping the last network bit local mask = self.mask |