diff options
Diffstat (limited to 'dhcp-model.lua')
-rw-r--r-- | dhcp-model.lua | 210 |
1 files changed, 193 insertions, 17 deletions
diff --git a/dhcp-model.lua b/dhcp-model.lua index 9a0839c..ceb4390 100644 --- a/dhcp-model.lua +++ b/dhcp-model.lua @@ -2,11 +2,55 @@ -- Copyright(c) 2007 A. Brodmann - Licensed under terms of GPL2 module (..., package.seeall) +--- get additional libraries require("validator") local subnet = {} local cfgdir = "/etc/dhcp/" +--- the tokenizer functions - must be dislocated into a library later +tokenizer = {} + +tokenizer.new = function( str, delim ) + local token = {} + token.value = str; + token.delim = delim; + token.pos = 1 + return token +end + +tokenizer.pos = function( value, substr, pos ) + local retval = pos + local done = false + while not done and retval <= #value do + if string.sub( value, retval, retval ) == substr then + done = true + else + retval = retval + 1 + end + end + + return retval +end + +tokenizer.next = function( token ) + if token.pos > #token.value then + return token, nil + end + + local strpos = tokenizer.pos( token.value, token.delim, token.pos ) + retval = string.sub(token.value, token.pos, strpos-1) + if retval == token.delim then + retval = "" + token.pos = token.pos + 1 + else + token.pos = strpos + 1 + end + + return token, retval +end +--- + dep_check = function () icode = 0 @@ -124,7 +168,59 @@ config_generate = function() return msg end - io.close( tmpfile ) + --- generate special hosts + subnets = get_subnets() + for k,v in ipairs( subnets ) do + spechostsfile = io.open( cfgdir .. v .. ".spechosts", "r" ) + if spechostsfile ~= nil then + spechosts = spechostsfile:read( "*a" ) + if spechosts == nil then + spechostsfile:close() + tmpfile:close() + os.remove( tmpfilename ) + msg = "Configuration Generation Failed!\n\n" .. + "Reason: failed to read special hosts file for '" .. v .. "'" + return msg + end + msg = validate_spechosts( spechosts ) + if #msg > 0 then + spechostsfile:close() + tmpfile:close() + os.remove( tmpfilename ) + msg = "Configuration Generation Failed!\n\n" .. + "Reason: " .. msg + return msg + end + + --- loop through all hosts + tmpfile:write("group {\n") + done = false + hosttoken = tokenizer.new( spechosts, "\n" ) + while not done do + hosttoken, nexthost = tokenizer.next( hosttoken ) + if nexthost ~= nil then + if string.sub( nexthost, 1, 1) ~= "#" then + spectoken = tokenizer.new( nexthost, ";" ) + spectoken, hostname = tokenizer.next( spectoken ) + spectoken, ip = tokenizer.next( spectoken ) + spectoken, mac = tokenizer.next( spectoken ) + spectoken, comment = tokenizer.next( spectoken ) + tmpfile:write(" host " .. hostname .. " {\n") + tmpfile:write(" hardware ethernet " .. mac .. ";\n") + tmpfile:write(" fixed-address " .. ip .. ";\n") + tmpfile:write(" }\n") + end + else + done = true + end + end + spechostsfile:close() + tmpfile:write("}\n\n") + end + end + --- + + tmpfile:close() os.rename( tmpfilename, "/etc/dhcp/dhcpd.conf" ) return "Configuration Generation Successful!\n" @@ -142,19 +238,7 @@ 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="text", value="" }) - } + local net = create_new_net( name, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ) for line in io.lines(filename) do if (string.sub(line, 1, 15) == "def-lease-time:") then @@ -182,9 +266,43 @@ subnet_read = function( name ) end end + net.spechosts.value = subnet_get_spechosts( name ) + return net end +subnet_get_spechosts = function( name ) + local retval = "" + local filename = cfgdir .. name .. ".spechosts" + if file_exists( filename ) then + local file = io.open( filename, "r" ) + if file ~= nil then + msg = file:read( "*a" ) + if msg ~= nil then + retval = msg + end + file:close() + end + end + + return retval +end + +subnet_update_spechosts = function( name, spechosts ) + local msg = ""; + local filename = cfgdir .. name .. ".spechosts" + + file, errmsg = io.open( filename, "wb+" ) + if file == nil then + msg = "Error: Failed to open " .. filename .. "(" .. errmsg .. ")!" + else + file:write( spechosts ) + file:close() + end + + return msg +end + read_settings = function() local filename = cfgdir .. "globalsettings.conf" local settings = create_new_settings( nil, nil, nil ) @@ -222,7 +340,64 @@ subnet_write = function( net ) file:write( "lease-range-end: " .. net.leaserangeend.value .. "\n" ) file:write( "wpad: " .. net.wpad.value .. "\n" ) file:close() - return cfe({ msg = "", fields = {}}), net + spec_msg = validate_spechosts( net.spechosts.value ) + if #spec_msg == 0 then + spec_msg = subnet_update_spechosts( net.name.value, net.spechosts.value ) + if #spec_msg > 0 then + msg = spec_msg + table.insert( fields, "spechosts" ) + end + else + msg = spec_msg + table.insert( fields, "spechosts" ) + end + return cfe({ msg = msg, fields = {}}), net +end + +validate_spechosts = function( spechosts ) + + local line = 1 + local msg = "" + local done = false + hosttoken = tokenizer.new( spechosts, "\n") + while not done do + hosttoken, nexthost = tokenizer.next( hosttoken ) + if nexthost ~= nil then + if string.sub(nexthost, 1, 1) ~= "#" then + fieldtoken = tokenizer.new( nexthost, ";") + fieldtoken, hostname = tokenizer.next( fieldtoken ) + fieldtoken, ip = tokenizer.next( fieldtoken ) + fieldtoken, mac = tokenizer.next( fieldtoken ) + fieldtoken, comment = tokenizer.next( fieldtoken ) + if hostname == nil then + msg = msg .. "hostname missing on line " .. line .. "!\n" + else + if not is_valid_hostname( hostname ) then + msg = msg .. "Invalid hostname on line " .. line .. "!\n" + end + end + if ip == nil then + msg = msg .. "ip missing on line " .. line .. "!\n" + else + if not validator.is_ipv4( ip ) then + msg = msg .. "Invalid ip on line " .. line .. "!\n" + end + end + if mac == nil then + msg = msg .. "mac missing on line " .. line .. "!\n" + else + if not validator.is_mac( mac ) then + msg = msg .. "Invalid mac on line " .. line .. "!\n" + end + end + end + line = line + 1 + else + done = true + end + end + + return msg end update_settings = function ( settings ) @@ -420,7 +595,7 @@ get_subnets = function () return retval end -create_new_net = function( name, defleasetime, maxleasetime, gateway, domainname, dnssrv1, dnssrv2, subnet, netmask, leaserangestart, leaserangeend, wpad ) +create_new_net = function( name, defleasetime, maxleasetime, gateway, domainname, dnssrv1, dnssrv2, subnet, netmask, leaserangestart, leaserangeend, wpad, spechosts ) 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" }, @@ -432,7 +607,8 @@ create_new_net = function( name, defleasetime, maxleasetime, gateway, domainname 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), value=nonil(wpad) } + wpad = { label="Web Proxy Auto Discovery", value=nonil(wpad), type="text" }, + spechosts = { label="Special Hosts Config", value=nonil(spechosts), type="text" } } return net |