Added DynDNS
This commit is contained in:
parent
9cfe671233
commit
baa4453186
20
DynDNS/README.md
Normal file
20
DynDNS/README.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# DynDNS
|
||||
|
||||
Dynamic DNS records can be used for assigning hostnames to local devices.
|
||||
|
||||
It combines **DHCPv4 server leases** with **IP neigh** and add ALL device addresses to DNS hostnames.
|
||||
|
||||
Can be used for assinging **RA addresses to device hostnames**, which are defaultly **NOT** assigned in OpenWrt.
|
||||
|
||||
Add this script to **dnsmasq's dhcp-script** option:
|
||||
```
|
||||
dhcp-script = lua /path/to/dyndns.lua
|
||||
```
|
||||
|
||||
Or via dhcpscript in uci:
|
||||
```
|
||||
config dnsmasq
|
||||
option dhcpscript 'lua /path/to/dyndns.lua'
|
||||
```
|
||||
|
||||
Also add `list addnhosts '/tmp/dyndns'` to make dnsmasq using DynDNS's hosts file.
|
212
DynDNS/dyndns.lua
Normal file
212
DynDNS/dyndns.lua
Normal file
|
@ -0,0 +1,212 @@
|
|||
-- 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 = "chata.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 print_table(node)
|
||||
local cache, stack, output = {},{},{}
|
||||
local depth = 1
|
||||
local output_str = "{\n"
|
||||
|
||||
while true do
|
||||
local size = 0
|
||||
for k,v in pairs(node) do
|
||||
size = size + 1
|
||||
end
|
||||
|
||||
local cur_index = 1
|
||||
for k,v in pairs(node) do
|
||||
if (cache[node] == nil) or (cur_index >= cache[node]) then
|
||||
|
||||
if (string.find(output_str,"}",output_str:len())) then
|
||||
output_str = output_str .. ",\n"
|
||||
elseif not (string.find(output_str,"\n",output_str:len())) then
|
||||
output_str = output_str .. "\n"
|
||||
end
|
||||
|
||||
-- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
|
||||
table.insert(output,output_str)
|
||||
output_str = ""
|
||||
|
||||
local key
|
||||
if (type(k) == "number" or type(k) == "boolean") then
|
||||
key = "["..tostring(k).."]"
|
||||
else
|
||||
key = "['"..tostring(k).."']"
|
||||
end
|
||||
|
||||
if (type(v) == "number" or type(v) == "boolean") then
|
||||
output_str = output_str .. string.rep('\t',depth) .. key .. " = "..tostring(v)
|
||||
elseif (type(v) == "table") then
|
||||
output_str = output_str .. string.rep('\t',depth) .. key .. " = {\n"
|
||||
table.insert(stack,node)
|
||||
table.insert(stack,v)
|
||||
cache[node] = cur_index+1
|
||||
break
|
||||
else
|
||||
output_str = output_str .. string.rep('\t',depth) .. key .. " = '"..tostring(v).."'"
|
||||
end
|
||||
|
||||
if (cur_index == size) then
|
||||
output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
|
||||
else
|
||||
output_str = output_str .. ","
|
||||
end
|
||||
else
|
||||
-- close the table
|
||||
if (cur_index == size) then
|
||||
output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
|
||||
end
|
||||
end
|
||||
|
||||
cur_index = cur_index + 1
|
||||
end
|
||||
|
||||
if (size == 0) then
|
||||
output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
|
||||
end
|
||||
|
||||
if (#stack > 0) then
|
||||
node = stack[#stack]
|
||||
stack[#stack] = nil
|
||||
depth = cache[node] == nil and depth + 1 or depth - 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
|
||||
table.insert(output,output_str)
|
||||
output_str = table.concat(output)
|
||||
|
||||
print(output_str)
|
||||
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 ~= "?" then
|
||||
for key,value in pairs(ip) do
|
||||
if non_fqdn then config = config .. "\r\n" .. value .. " " .. hostname end
|
||||
if network_domain then config = config .. "\r\n" .. value .. " " .. hostname .. "." .. network_domain end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
file = io.open(output_file, "w")
|
||||
file:write(config)
|
||||
file:close()
|
||||
|
||||
os.execute(reload_command)
|
Loading…
Reference in a new issue