Files
ruantiblock_openwrt/ruantiblock-mod-lua/files/usr/lib/lua/ruab_sum_ip.lua
T

208 lines
6.2 KiB
Lua
Raw Normal View History

2020-06-19 20:43:08 +03:00
--[[
(с) 2020 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
--]]
local it = require("iptool")
HOSTS_LIMIT = 0
NETS_LIMIT = 0
local function sort_ip_list(t)
local t2 = {}
for k in pairs(t) do
t2[#t2 + 1] = k
end
table.sort(t2, function(a, b) return it.ip_to_int(a) < it.ip_to_int(b) end)
return t2
end
local function group_ip_ranges(ip_list, raw_list)
local function remove_items(start, stop)
for i = start, stop do
if raw_list[i] then
raw_list[i] = nil
return
end
local item = it.int_to_ip(i)
if raw_list[item] then
raw_list[it.int_to_ip(i)] = nil
end
end
end
local start, stop, last_call
local hosts = 1
local i = 0
return function()
local ret_val
local ip
repeat
i = i + 1
ip = ip_list[i]
if ip then
local ip_dec = it.ip_to_int(ip)
if stop and (stop + 1) == ip_dec then
hosts = hosts + 1
else
if hosts > 1 and hosts >= HOSTS_LIMIT then
if raw_list then
remove_items(start, stop)
end
ret_val = {[1] = start, [2] = stop}
start = ip_dec
stop = ip_dec
hosts = 1
break
end
start = ip_dec
end
stop = ip_dec
elseif not last_call then
if hosts > 1 and hosts >= HOSTS_LIMIT then
if raw_list then
remove_items(start, stop)
end
ret_val = {[1] = start, [2] = stop}
last_call = true
break
end
end
until not ip
return ret_val
end
end
local function sort_net_list(t)
local t2 = {}
for k, v in pairs(t) do
local ip, pref = it.get_network_addr(k)
t2[#t2 + 1] = {[1] = ip, [2] = pref}
end
table.sort(t2, function(a, b) return a[1] < b[1] end)
return t2
end
local function group_nets(cidr_list, raw_list)
local function remove_items(start, stop)
for i = start, stop, 256 do
local item = it.int_to_ip(i) .. "/24"
if raw_list[item] then
raw_list[item] = nil
end
end
end
local start, stop, last_call, curr_supernet
local nets = 1
local i = 0
return function()
local ret_val
local cidr
repeat
i = i + 1
cidr = cidr_list[i]
if cidr then
local network_address, prefixlen
if type(cidr) == "string" then
network_address, prefixlen = it.get_network_addr(cidr)
elseif type(cidr) == "table" then
network_address, prefixlen = cidr[1], cidr[2]
end
if prefixlen == 24 then
local supernet = it.get_supernet({[1] = network_address, [2] = prefixlen}, 16)
if stop and supernet == curr_supernet and (stop + 256) == network_address then
nets = nets + 1
else
if nets > 1 and nets >= NETS_LIMIT then
if raw_list then
remove_items(start, stop)
end
ret_val = {[1] = start, [2] = stop + 255}
start = network_address
stop = network_address
nets = 1
curr_supernet = supernet
break
end
start = network_address
curr_supernet = supernet
end
stop = network_address
end
elseif not last_call then
if nets > 1 and nets >= NETS_LIMIT then
if raw_list then
remove_items(start, stop)
end
ret_val = {[1] = start, [2] = stop + 255}
last_call = true
break
end
end
until not cidr
return ret_val
end
end
local function summarize_ranges(ip_iter)
local s_range_iter
return function()
-- lua >= 5.2
--::check_prefix::
if s_range_iter then
repeat
local ip_t = s_range_iter()
if ip_t then
return ip_t
end
until not ip_t
end
local ip_range = ip_iter()
if ip_range then
s_range_iter = it.summarize_address_range(ip_range[1], ip_range[2])
if s_range_iter then
-- lua >= 5.2
--goto check_prefix
-- lua < 5.2
repeat
local ip_t = s_range_iter()
if ip_t then
return ip_t
end
until not ip_t
--
end
else
return
end
end
end
function summarize_ip_ranges(ip_list, modify_raw_list)
local summ_iter = summarize_ranges(group_ip_ranges(sort_ip_list(ip_list),
modify_raw_list and ip_list)
)
return function()
repeat
local ip_t = summ_iter()
if ip_t and ip_t[2] == 32 then
if modify_raw_list then
ip_list[it.int_to_ip(ip_t[1])] = true
end
else
return ip_t
end
until not ip_t
end
end
function summarize_nets(cidr_list, modify_raw_list)
return summarize_ranges(group_nets(sort_net_list(cidr_list),
modify_raw_list and cidr_list))
end
return {
summarize_ip_ranges = summarize_ip_ranges,
summarize_nets = summarize_nets,
}