-- acf model for /etc/dhcp/* -- Copyright(c) 2007 A. Brodmann - Licensed under terms of GPL2 module (..., package.seeall) require("lfs") require("validator") local subnet = { } local cfgdir = "/etc/dhcp/" dep_check = function () icode = 0 retval = {} lpos = require "posix" ptr, msg, code = lpos.access("/etc/dhcp") if ptr == nil then table.insert(retval, "/etc/dhcp") icode = icode + 1 end ptr, msg, code = lpos.access("/usr/sbin/dhcpd") if ptr == nil then table.insert(retval, "/usr/sbin/dhcpd") icode = icode + 1 end ptr, msg, code = lpos.access("/etc/init.d/dhcpd") if ptr == nil then table.insert(retval, "/etc/init.d/dhcpd") icode = icode + 1 end if icode == 0 then retval = nil end return retval end subnet_read = function( name ) local filename = cfgdir .. name .. ".subnet" local net = { name = cfe({ type="message", value=name, label="Name" }), defleasetime = cfe({ label="Default Lease Time" }), maxleasetime = cfe({ label="Maximum Lease Time" }), gateway = cfe({ label="Gateway"}), domainname = cfe({ label="Domainname" }), dnssrv1 = cfe({ label="DNS Server 1" }), dnssrv2 = cfe({ label="DNS Server 2" }), subnet = cfe({ label="Subnet" }), netmask = cfe({ label="Netmask" }), leaserangestart = cfe({ label="Lease Range Start" }), leaserangeend = cfe({ label="Lease Range End" }), wpad = cfe({ label="Web Proxy Auto Discovery", type="select", option = { "yes", "no" } }) } for line in io.lines(filename) do if (string.sub(line, 1, 15) == "def-lease-time:") then net.defleasetime.value = string.sub(line, 17) elseif (string.sub(line, 1, 15) == "max-lease-time:") then net.maxleasetime.value = string.sub(line, 17) elseif (string.sub(line, 1, 8) == "gateway:") then net.gateway.value = string.sub(line, 10) elseif (string.sub(line, 1, 12) == "domain-name:") then net.domainname.value = string.sub(line, 14) elseif (string.sub(line, 1, 10) == "dns-srv-1:") then net.dnssrv1.value = string.sub(line, 12) elseif (string.sub(line, 1, 10) == "dns-srv-2:") then net.dnssrv2.value = string.sub(line, 12) elseif (string.sub(line, 1, 7) == "subnet:") then net.subnet.value = string.sub(line, 9) elseif (string.sub(line, 1, 8) == "netmask:") then net.netmask.value = string.sub(line, 10) elseif (string.sub(line, 1, 18) == "lease-range-start:") then net.leaserangestart.value = string.sub(line, 20) elseif (string.sub(line, 1, 16) == "lease-range-end:") then net.leaserangeend.value = string.sub(line, 18) elseif (string.sub(line, 1, 5) == "wpad:") then net.wpad.value = string.sub(line, 7) end end return net end subnet_write = function( net ) msg, fields = validate_network( net ) if #msg > 0 then return cfe({ msg = msg, fields = fields }), net end local filename = cfgdir .. net.name.value .. ".subnet" local file = io.open( filename, "w+" ) file:write( "def-lease-time: " .. net.defleasetime.value .. "\n" ) file:write( "max-lease-time: " .. net.maxleasetime.value .. "\n" ) file:write( "gateway: " .. net.gateway.value .. "\n" ) file:write( "domain-name: " .. net.domainname.value .. "\n" ) file:write( "dns-srv-1: " .. net.dnssrv1.value .. "\n" ) file:write( "dns-srv-2: " .. net.dnssrv2.value .. "\n" ) file:write( "subnet: " .. net.subnet.value .. "\n" ) file:write( "netmask: " .. net.netmask.value .. "\n" ) file:write( "lease-range-start: " .. net.leaserangestart.value .. "\n" ) file:write( "lease-range-end: " .. net.leaserangeend.value .. "\n" ) file:write( "wpad: " .. net.wpad.value .. "\n" ) file:close() return cfe({ msg = "", fields = {}}), net end subnet_create = function( net ) if file_exists( net.name.value ) then return cfe({ msg = "This subnet already exists!", fields = {}}), net end retcode, net = subnet_write( net ) return retcode, net end _tonumber = function( value ) ret = tonumber( value ) if (ret == nil) then ret = 0 end return ret end validate_network = function( net ) fields = { "none" } msg = "" if #net.name.value < 4 then table.insert(fields, "name") msg = msg .. "Minimum network name length is 4 characters!\n" end if net.name.value == "" then table.insert(fields, "name") msg = msg .. "<new> is not a valid network name!\n" end if not validator.is_integer_in_range(_tonumber(net.defleasetime.value), 1800, 86400) then table.insert(fields, "defleasetime") msg = msg .. "Default-Lease-Time must be: 1800 < x < 86400\n" end if not validator.is_integer_in_range(_tonumber(net.maxleasetime.value), 1800, 86400) then table.insert(fields, "maxleasetime") msg = msg .. "Maximum-Lease-Time must be: 1800 < x < 86400\n" end if not validator.is_ipv4(net.gateway.value) then table.insert(fields, "gateway") msg = msg .. "Gateway: invalid IPv4 address!\n" end if not validator.is_ipv4(net.dnssrv1.value) then table.insert(fields, "dnssrv1") msg = msg .. "DNS Server 1: invalid IPv4 address!\n" end if not validator.is_ipv4(net.dnssrv2.value) then if #net.dnssrv2.value > 0 then table.insert(fields, "dnssrv2") msg = msg .. "DNS Server 2: invalid IPv4 address!\n" end end if not validator.is_ipv4(net.subnet.value) then table.insert(fields, "subnet") msg = msg .. "Subnet: invalid IPv4 address!\n" end if not validator.is_ipv4(net.netmask.value) then table.insert(fields, "netmask") msg = msg .. "Netmask: invalid IPv4 address!\n" end if not validator.is_ipv4(net.leaserangestart.value) then if #net.leaserangestart.value > 0 then table.insert(fields, "leaserangestart") msg = msg .. "Lease-Range-Start: invalid IPv4 address!\n" end end if not validator.is_ipv4(net.leaserangeend.value) then if #net.leaserangeend.value > 0 then table.insert(fields, "leaserangeend") msg = msg .. "Lease-Range-End: invalid IPv4 address!\n" end end return msg, fields end file_exists = function( filename ) retval = false fn = cfgdir .. net.name.value .. ".subnet" file = io.open( fn, "r" ) if file ~= nil then retval = true file:close() end return retval end read_file = function ( filename ) local contents = "" local line = "" local file = io.open( filename, "r" ) if file ~= nil then line = file:read( "*l" ) while line ~= nil do contents = contents .. "\n" .. line line = file:read( "*l" ) end file:close() else contents = "\n Error: File not found!\n\n" end return contents end is_running = function( process ) local retval = false local file = io.popen("pidof " .. process) if file ~= nil then local line = file:read( "*l" ) file:close() if #line > 0 then retval = true end end return retval end get_dhcpd_version = function() local retval = "dhcpd" local file = io.popen("/usr/sbin/dhcpd --version") if file ~= nil then local line = file:read( "*a" ) if #line > 0 then retval = line end file:close() end return retval end service_control = function ( command ) local retval = "" local line = "" local file = io.popen( "/etc/init.d/dhcpd " .. command ) if file ~= nil then line = file:read( "*a" ) while line ~= nil do retval = retval .. "\n" .. line line = file:read( "*l" ) end file:close() end return retval end function nonil( value ) local retval = "" if value ~= nil then retval = value end return retval end get_subnets = function () local retval = retval or {} for sn in lfs.dir( cfgdir ) do if string.sub(sn, -7) == ".subnet" then table.insert(retval, string.sub(sn, 1, -8)) end end return retval end create_new_net = function( name, defleasetime, maxleasetime, gateway, domainname, dnssrv1, dnssrv2, subnet, netmask, leaserangestart, leaserangeend, wpad ) net = { name = { label="Name", value=nonil(name), type="message" }, defleasetime = { label="Default Lease Time", value=nonil(defleasetime), type="text" }, maxleasetime = { label="Maximum Lease Time", value=nonil(maxleasetime), type="text" }, gateway = { label="Gateway", value=nonil(gateway), type="text" }, domainname = { label="Domainname", value=nonil(domainname), type="text" }, dnssrv1 = { label="DNS Server 1", value=nonil(dnssrv1), type="text" }, dnssrv2 = { label="DNS Server 2", value=nonil(dnssrv2), type="text" }, subnet = { label="Subnet", value=nonil(subnet), type="text" }, netmask = { label="Netmask", value=nonil(netmask), type="text" }, leaserangestart = { label="Lease Range Start", value=nonil(leaserangestart), type="text" }, leaserangeend = { label="Lease Range End", value=nonil(leaserangeend), type="text" }, wpad = { label="Web Proxy Auto Discovery", value=nonil(wpad), type="select", value=nonil(wpad), option = { "yes", "no"} } } if net.wpad.value == "" then net.wpad.value = "no" end return net end