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
|