diff options
Diffstat (limited to 'dnsmasq-model.lua')
-rw-r--r-- | dnsmasq-model.lua | 237 |
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 |