summaryrefslogtreecommitdiffstats
path: root/lib/ipcalc.lua
blob: fb05561a2031fb75d0510dde5900a0eb2f765941 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

module (..., package.seeall)
require("bit")

function iptoint(str)
	-- TODO: support "a.", "a.b.", "a.b.c."
        local a,b,c,d = string.match(str, "(%d+).(%d+).(%d+).(%d+)")
        if a and b and c and d then
		return bit.lshift(a, 24) + bit.lshift(b, 16) + bit.lshift(c, 8) + d
        end
        return nil
end

function nettoint(net, mask)
	if mask == nil then
		mask = string.match(net, "/(.*)")
		if mask == nil then
			-- no mask provied at all
			return iptoint(net)
		end
		net = string.gsub(net, "/.*", "")
	end

	local n = tonumber(mask)
	if n == nil then
		-- mask is a.b.c.d style
		return iptoint(net), iptoint(mask)
	end

	-- mask is /24 style
	if n > 32 then
		return nil
	end
	return iptoint(net), bit.band(bit.lshift(0xfffffffff, 32 - n), 0xffffffff)
end
		

-- same_subnet - check if address is in net/mask
-- synopsis:
-- 	same_subnet(addr, net[/mask][, mask])
-- example:
-- 	same_subnet("10.0.0.1", "10.0.0.0/24")
-- 	same_subnet("10.0.0.1", "10.0.0.0", "24")
-- 	same_subnet("10.0.0.1", "10.0.0.0/255.255.255.0")
-- 	same_subnet("10.0.0.1", "10.0.0.0", "255.255.255.0")

function same_subnet(addr, net, mask)
	local a = iptoint(addr)
	local n, m = nettoint(net, mask)
	if a and n and m then
		return bit.band(a, m) == bit.band(n, m)
	end
	return false
end