192 lines
3.9 KiB
Lua
192 lines
3.9 KiB
Lua
-- Configuration
|
|
|
|
local lookup_dhcp_leases = true
|
|
local dhcp_leases_file = "/tmp/dhcp.leases"
|
|
|
|
local lookup_ip_neigh = true
|
|
|
|
local non_fqdn = true
|
|
local network_domain = ".lan"
|
|
|
|
local output_file = "/tmp/dyndns"
|
|
|
|
local reload_command = "/etc/init.d/dnsmasq reload"
|
|
|
|
|
|
function split(inputstr, sep)
|
|
if sep == nil then
|
|
sep = "%s"
|
|
end
|
|
local t={}
|
|
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
|
|
table.insert(t, str)
|
|
end
|
|
return t
|
|
end
|
|
|
|
function new()
|
|
return {hostname = "?", ip = {}}
|
|
end
|
|
|
|
function contains(tab, val)
|
|
for index, value in ipairs(tab) do
|
|
if value == val then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function ipv4(ip)
|
|
local chunks = {ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")}
|
|
if (#chunks == 4) then
|
|
for _,v in pairs(chunks) do
|
|
if (tonumber(v) < 0 or tonumber(v) > 255) then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function ipv6(ip)
|
|
local _, chunks = ip:gsub("[%a%d]+%:?", "")
|
|
if chunks == 8 then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function count(T)
|
|
local count = 0
|
|
for _ in pairs(T) do count = count + 1 end
|
|
return count
|
|
end
|
|
|
|
function read_file(path)
|
|
local file = io.open(path, "rb")
|
|
if not file then return nil end
|
|
local content = file:read "*a"
|
|
file:close()
|
|
return content
|
|
end
|
|
|
|
function pairs_by_keys(t, f)
|
|
local a = {}
|
|
for n in pairs(t) do
|
|
table.insert(a, n)
|
|
end
|
|
table.sort(a, f)
|
|
local i = 0 -- iterator variable
|
|
local iter = function () -- iterator function
|
|
i = i + 1
|
|
if a[i] == nil then
|
|
return nil
|
|
else
|
|
return a[i], t[a[i]]
|
|
end
|
|
end
|
|
return iter
|
|
end
|
|
|
|
function sort_table(my_table)
|
|
local t = {}
|
|
for title,value in pairs_by_keys(my_table) do
|
|
table.insert(t, { title = title, value = value })
|
|
end
|
|
my_table = t
|
|
return my_table
|
|
end
|
|
|
|
function compare_tables(a,b)
|
|
if #a ~= #b then return false end
|
|
local t1,t2 = {}, {}
|
|
for k,v in pairs(a) do
|
|
t1[k] = (t1[k] or 0) + 1
|
|
end
|
|
for k,v in pairs(b) do
|
|
t2[k] = (t2[k] or 0) + 1
|
|
end
|
|
for k,v in pairs(t1) do
|
|
if v ~= t2[k] then return false end
|
|
end
|
|
return true
|
|
end
|
|
|
|
|
|
array = {}
|
|
|
|
if lookup_dhcp_leases then
|
|
|
|
local dhcp_file = assert(io.popen('cat ' .. dhcp_leases_file, 'r'))
|
|
local dhcp_table = split(dhcp_file:read('*all'), "\r\n")
|
|
dhcp_file:close()
|
|
|
|
for key,value in pairs(dhcp_table) do
|
|
local dhcp_lease = split(value, " ")
|
|
local mac = dhcp_lease[2]
|
|
if not array[mac] then
|
|
array[mac] = new()
|
|
array[mac]["hostname"] = dhcp_lease[4]
|
|
end
|
|
if not contains(array[mac]["ip"], dhcp_lease[3]) then
|
|
table.insert(array[mac]["ip"], dhcp_lease[3])
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
if lookup_ip_neigh then
|
|
|
|
local neigh_file = assert(io.popen('ip neigh', 'r'))
|
|
local neigh_table = split(neigh_file:read('*all'), "\r\n")
|
|
neigh_file:close()
|
|
|
|
for key,value in pairs(neigh_table) do
|
|
local neigh = split(value, " ")
|
|
local mac = neigh[5]
|
|
local ip = neigh[1]
|
|
if mac and ip then
|
|
if not array[mac] then
|
|
array[mac] = new()
|
|
end
|
|
if not contains(array[mac]["ip"], ip) then
|
|
table.insert(array[mac]["ip"], ip)
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
config = ""
|
|
|
|
for key,value in pairs(array) do
|
|
local mac = key
|
|
local ip = value["ip"]
|
|
local hostname = value["hostname"]
|
|
if hostname ~= "?" and hostname ~= "*" then
|
|
for key,value in pairs(ip) do
|
|
line = value
|
|
if non_fqdn then line = line .. " " .. hostname end
|
|
if network_domain then line = line .. " " .. (hostname .. network_domain) end
|
|
if line ~= value then config = config .. "\r\n" .. line end
|
|
end
|
|
end
|
|
end
|
|
|
|
config_file = read_file(output_file)
|
|
if config_file == nil then config_file = "" end
|
|
|
|
c1 = sort_table(split(config_file, "\r\n"))
|
|
c2 = sort_table(split(config, "\r\n"))
|
|
|
|
if not compare_tables(c1, c2) then
|
|
file = io.open(output_file, "w")
|
|
file:write(config)
|
|
file:close()
|
|
os.execute(reload_command)
|
|
end
|