summaryrefslogtreecommitdiffstats
path: root/dnsmasq-model.lua
diff options
context:
space:
mode:
Diffstat (limited to 'dnsmasq-model.lua')
-rw-r--r--dnsmasq-model.lua237
1 files changed, 237 insertions, 0 deletions
diff --git a/dnsmasq-model.lua b/dnsmasq-model.lua
new file mode 100644
index 0000000..aec875f
--- /dev/null
+++ b/dnsmasq-model.lua
@@ -0,0 +1,237 @@
+module(..., package.seeall)
+
+-- Load libraries
+require("modelfunctions")
+require("fs")
+require("format")
+require("posix")
+require("validator")
+
+-- Set variables
+local configfile = "/etc/dnsmasq.conf"
+local processname = "dnsmasq"
+local packagename = "dnsmasq"
+local baseurl = "/etc/"
+local descr = {
+}
+
+-- ################################################################################
+-- LOCAL FUNCTIONS
+
+local function validateconfig(config)
+ local success = true
+ if config.value.IPSEND and not validator.is_ipv4(config.value.IPSEND.value) then
+ config.value.IPSEND.errtxt = "Invalid IP address"
+ success = false
+ end
+ if config.value.IP and not validator.is_ipv4(config.value.IP.value) then
+ config.value.IP.errtxt = "Invalid IP address"
+ success = false
+ end
+ return success, config
+end
+
+local function validatedomain(domain)
+ local success = false
+ local domains = getDomains()
+ domain.value.domain.errtxt = "Invalid domain"
+ for i,name in ipairs(domains.value) do
+ if name == domain.value.domain.value then
+ domain.value.domain.errtxt = nil
+ success = true
+ break
+ end
+ end
+ for i,name in ipairs(domain.value.iplist.value) do
+ if not validator.is_ipv4(name) then
+ domain.value.iplist.errtxt = "Invalid IP address"
+ success = false
+ break
+ end
+ end
+ return success, domain
+end
+
+-- ################################################################################
+-- PUBLIC FUNCTIONS
+
+function startstop_service(action)
+ return modelfunctions.startstop_service(processname, action)
+end
+
+function getstatus()
+ return modelfunctions.getstatus(processname, packagename, "DNS Masq Status")
+end
+
+function getconfig()
+ local conf = format.parse_ini_file(fs.read_file(configfile), "") or {}
+require ("html")
+
+ local output = {}
+ output.DOMAIN = cfe({ value = conf.domain or "", label="Local Domain to use",
+ descr="Internal Domain for your LAN" })
+ output.INTERFACE = cfe({ value=conf.interface, label="Interface" })
+ output.IP = cfe({ value=conf["listen-address"] or "", label="IP address to listen on" })
+ output.RANGE = cfe ({value=conf["dhcp-range"] or "", label="Range of IPs", descr="First,Last,Netmask,Time in hours"})
+
+ -- APP.logevent(html.cfe_unpack(output))
+
+ return cfe({ type="group", value=output, label="DNS Masq Config" })
+end
+
+function setconfig(config)
+ local success, config = validateconfig(config)
+
+ if success then
+ local file = fs.read_file(configfile)
+ file = format.update_ini_file(file,"","domain",config.value.LOCALD.value)
+ file = format.update_ini_file(file,"","interface",config.value.INTERFACE.value)
+ file = format.update_ini_file(file,"","listen-address",config.value.IP.value)
+ file = format.update_ini_file(file,"","dhcp-range",config.value.RANGE.value)
+ fs.write_file(configfile, file)
+ else
+ config.errtxt = "Failed to set config"
+ end
+
+ return config
+end
+
+function getconfigfile()
+ -- FIXME Validate
+ return modelfunctions.getfiledetails(configfile)
+end
+
+function setconfigfile(filedetails)
+ -- FIXME Validate
+ return modelfunctions.setfiledetails(filedetails, {configfile})
+end
+
+function getIPs()
+ local ipdir = baseurl.."ip"
+ local iplist = cfe({ type="list", value={}, label="IP prefixes to respond to" })
+ if fs.is_dir(ipdir) then
+ for i,name in ipairs(posix.dir(ipdir)) do
+ if not string.match(name, "^%.") then
+ if (fs.is_file(ipdir.."/"..name)) then
+ table.insert(iplist.value, name)
+ end
+ end
+ end
+ end
+ return cfe({ type="group", value={iplist=iplist} })
+end
+
+function setIPs(iplist)
+ local reverseIPs = {}
+ for i,name in ipairs(iplist.value.iplist.value) do
+ -- check if a valid (or partial) ip
+ if not validator.is_partial_ipv4(name) then
+ iplist.value.iplist.errtxt = "Invalid IP address"
+ iplist.errtxt = "Failed to set IP list"
+ break
+ end
+ reverseIPs[name] = i
+ end
+ if not iplist.errtxt then
+ local currentIPlist = getIPs()
+ for i,name in ipairs(currentIPlist.value.iplist.value) do
+ if reverseIPs[name] then
+ reverseIPs[name] = nil
+ else
+ -- need to delete the file
+ local f = io.popen("rm "..baseurl.."ip/"..name)
+ f:close()
+ end
+ end
+ for name in pairs(reverseIPs) do
+ -- need to create the file
+ local f = io.popen("touch "..baseurl.."ip/"..name)
+ f:close()
+ end
+ end
+ return iplist
+end
+
+function getDomains()
+ local domaindir = baseurl.."servers"
+ local domainlist = cfe({ type="list", value={}, label="DNS Server Domains" })
+ if fs.is_dir(domaindir) then
+ for i,name in ipairs(posix.dir(domaindir)) do
+ if not string.match(name, "^%.") then
+ if (fs.is_file(domaindir.."/"..name)) then
+ table.insert(domainlist.value, name)
+ end
+ end
+ end
+ end
+ return domainlist
+end
+
+function getNewDomain()
+ local domain = cfe({ label="Domain" })
+ return cfe({ type="group", value={domain=domain} })
+end
+
+function setNewDomain(domain)
+ if "" ~= string.gsub(domain.value.domain.value..".", "%w+%.", "") then
+ domain.value.domain.errtxt = "Invalid domain"
+ domain.errtxt = "Failed to create domain"
+ elseif fs.is_file(baseurl.."servers/"..domain.value.domain.value) then
+ domain.value.domain.errtxt = "Domain already exists"
+ domain.errtxt = "Failed to create domain"
+ else
+ local f = io.popen("touch "..baseurl.."servers/"..domain.value.domain.value)
+ f:close()
+ domain.descr = "Created domain"
+ end
+ return domain
+end
+
+function getDomain(getdomainname)
+ local domain = cfe({ value=getdomainname, label="Domain", errtxt="Invalid domain" })
+ local iplist = cfe({ type="list", value={}, label="List of DNS servers" })
+ local domains = getDomains()
+ for i,name in ipairs(domains.value) do
+ if name == getdomainname then
+ domain.errtxt = nil
+ break
+ end
+ end
+ if not domain.errtxt then
+ local content = fs.read_file(baseurl.."servers/"..getdomainname)
+ for name in string.gmatch(content.."\n", "([^\n]+)\n") do
+ table.insert(iplist.value, name)
+ end
+ end
+ return cfe({ type="group", value={domain=domain, iplist=iplist} })
+end
+
+function setDomain(domain)
+ local success, domain = validatedomain(domain)
+ if success then
+ fs.write_file(baseurl.."servers/"..domain.value.domain.value,
+ table.concat(domain.value.iplist.value, "\n") )
+ else
+ domain.errtxt = "Failed to save domain"
+ end
+ return domain
+end
+
+function deleteDomain(domainname)
+ local cmdresult = cfe({ value="Domain not deleted", label="Delete domain result", errtxt="Invalid domain" })
+ local domains = getDomains()
+ if domainname == "@" then
+ cmdresult.errtxt = "Cannot delete root domain"
+ else
+ for i,name in ipairs(domains.value) do
+ if name == domainname then
+ local f = io.popen("rm "..baseurl.."servers/"..name)
+ f:close()
+ cmdresult.errtxt = nil
+ cmdresult.value = "Domain deleted"
+ break
+ end
+ end
+ end
+ return cmdresult
+end