summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Brodmann <andreas.brodmann@gmail.com>2007-11-16 22:09:29 +0000
committerAndreas Brodmann <andreas.brodmann@gmail.com>2007-11-16 22:09:29 +0000
commit365f56f2b68b036352d12daa13695b662a9d0017 (patch)
tree8fe9bc1a6b845fafa6c29a52127c7aa9940dc520
parent4d2aa0242d937da6b3431dbdb743a02669628023 (diff)
downloadacf-dhcp-365f56f2b68b036352d12daa13695b662a9d0017.tar.bz2
acf-dhcp-365f56f2b68b036352d12daa13695b662a9d0017.tar.xz
/acf/dhcp: added static/dynamic host behaviour on a per subnet basis
git-svn-id: svn://svn.alpinelinux.org/acf/dhcp/trunk@326 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r--dhcp-controller.lua6
-rw-r--r--dhcp-createnet-html.lsp11
-rw-r--r--dhcp-editnet-html.lsp28
-rw-r--r--dhcp-model.lua304
4 files changed, 268 insertions, 81 deletions
diff --git a/dhcp-controller.lua b/dhcp-controller.lua
index 00f213d..fc0e6f8 100644
--- a/dhcp-controller.lua
+++ b/dhcp-controller.lua
@@ -127,7 +127,7 @@ editnet = function ( self )
tmp = self.clientdata
net = self.model.create_new_net( tmp.name, tmp.defleasetime, tmp.maxleasetime, tmp.gateway,
tmp.domainname, tmp.dnssrv1, tmp.dnssrv2, tmp.subnet, tmp.netmask, tmp.leaserangestart,
- tmp.leaserangeend, tmp.wpad, tmp.spechosts )
+ tmp.leaserangeend, tmp.wpad, tmp.statichosts, tmp.unknownclients, tmp.dynamichosts )
errcode, net = self.model.subnet_write( net )
return ( cfe({ option = option, value = net, errcode = errcode }) )
end
@@ -150,13 +150,13 @@ createnet = function ( self )
}
if self.clientdata.cmd == "new" then
- net = self.model.create_new_net( "<new>", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil )
+ net = self.model.create_new_net( "<new>", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil )
return ( cfe({ option = option, value = net, errcode = { msg = "", fields = nil }}) )
elseif self.clientdata.cmd == "create" then
tmp = self.clientdata
net = self.model.create_new_net( tmp.name, tmp.defleasetime, tmp.maxleasetime,
tmp.gateway, tmp.domainname, tmp.dnssrv1, tmp.dnssrv2, tmp.subnet,
- tmp.netmask, tmp.leaserangestart, tmp.leaserangeend, tmp.wpad, "" )
+ tmp.netmask, tmp.leaserangestart, tmp.leaserangeend, tmp.wpad, "", tmp.unknownclients, "" )
errcode, net = self.model.subnet_create( net )
if #errcode.msg == 0 then
self.conf.type = "redir"
diff --git a/dhcp-createnet-html.lsp b/dhcp-createnet-html.lsp
index 2fe5a45..dc5d88f 100644
--- a/dhcp-createnet-html.lsp
+++ b/dhcp-createnet-html.lsp
@@ -27,5 +27,16 @@
<tr><td><nobr>WPAD:</nobr></td><td><input type="text" name="wpad" value="<? io.write(net.wpad.value) ?>"></td></tr>
<tr><td><nobr>Lease Range Start:</nobr></td><td><input type="text" name="leaserangestart" value="<? io.write(net.leaserangestart.value) ?>"></td></tr>
<tr><td><nobr>Lease Range End:</nobr></td><td><input type="text" name="leaserangeend" value="<? io.write(net.leaserangeend.value) ?>"></td></tr>
+ <tr><td><nobr>Unknown Clients</nobr></td><td><select name="unknownclients" size="1">
+<?
+ if net.unknownclients.value == "permit" then
+ io.write(" <option selected>permit</option>\n");
+ io.write(" <option>deny</option>\n");
+ else
+ io.write(" <option>permit</option>\n");
+ io.write(" <option selected>deny</option>\n");
+ end
+?>
+ </select></td></tr>
<tr><td></td><td><input type=submit name=cmd value="create" style="width:100px"></form><form action="<? io.write(option.script .. option.prefix .. option.controller .. "/home") ?> method="POST">
<input type=submit name="cmd" value="back" style="width:100px"></form></td></tr></table>
diff --git a/dhcp-editnet-html.lsp b/dhcp-editnet-html.lsp
index ea281a0..9bab76b 100644
--- a/dhcp-editnet-html.lsp
+++ b/dhcp-editnet-html.lsp
@@ -13,9 +13,10 @@
end
?>
-<form action="<? io.write(option.script .. option.prefix ..
+<form name="mainform" action="<? io.write(option.script .. option.prefix ..
option.controller .. "/" .. option.action .. option.extra) ?>" method="POST">
<input type="hidden" name="name" value="<? io.write(net.name.value) ?>">
+<input type="hidden" name="dynhost1" value="">
<table>
<tr><td><nobr>Subnet:</nobr></td><td><input type="text" name="subnet" value="<? io.write(net.subnet.value) ?>"></td></tr>
<tr><td><nobr>Netmask:</nobr></td><td><input type="text" name="netmask" value="<? io.write(net.netmask.value) ?>"></td></tr>
@@ -28,11 +29,22 @@
<tr><td><nobr>WPAD:</nobr></td><td><input type="text" name="wpad" value="<? io.write(net.wpad.value) ?>"></td></tr>
<tr><td><nobr>Lease Range Start:</nobr></td><td><input type="text" name="leaserangestart" value="<? io.write(net.leaserangestart.value) ?>"></td></tr>
<tr><td><nobr>Lease Range End:</nobr></td><td><input type="text" name="leaserangeend" value="<? io.write(net.leaserangeend.value) ?>"></td></tr>
+ <tr><td><nobr>Unknown Clients</nobr></td><td><select name="unknownclients" size="1">
+<?
+ if net.unknownclients.value == "permit" then
+ io.write(" <option selected>permit</option>\n");
+ io.write(" <option>deny</option>\n");
+ else
+ io.write(" <option>permit</option>\n");
+ io.write(" <option selected>deny</option>\n");
+ end
+?>
+ </select></td></tr>
<form action="<? io.write(option.script .. option.prefix .. option.controller .. "/home") ?>" method="POST">
</td></tr></table>
<br><br>
-<h2>Subnet: Special Hosts</h2>
+<h2>Subnet: Static Hosts</h2>
Enter one host per line in the format: <i>hostname;ip;mac;comment</i><br>
<table>
<tr><td>Hostname</td><td>[a-z], [0-9], -</td></tr>
@@ -40,7 +52,17 @@ Enter one host per line in the format: <i>hostname;ip;mac;comment</i><br>
<tr><td>MAC</td><td>XX:XX:XX:XX:XX:XX</td></tr>
</table>
<table>
-<tr><td><textarea name="spechosts" style="width:600px;"><? io.write( net.spechosts.value ) ?></textarea></td></tr>
+<tr><td><textarea name="statichosts" style="width:600px;"><? io.write( net.statichosts.value ) ?></textarea></td></tr>
+</table><br>
+<h2>Subnet: Dynamic Hosts</h2>
+Enter one host per line in the format: <i>hostname;mac;comment</i><br>
+<table>
+<tr><td>Hostname</td><td>[a-z], [0-9], -</td></tr>
+<tr><td>MAC</td><td>XX:XX:XX:XX:XX:XX</td></tr>
+</table>
+<table>
+<tr><td><div id="dynamic"><textarea name="dynamichosts" style="width:600px;"><? io.write( net.dynamichosts.value ) ?></textarea></div></td></tr>
+</table><br>
<tr><td><input type=submit name="cmd" value="update" style="width:100px"></form>
<form action="<? io.write(option.script .. option.prefix .. option.controller .. "/delnet") ?>" method="POST">
<input type=submit name="cmd" value="delete" style="width:100px">
diff --git a/dhcp-model.lua b/dhcp-model.lua
index b16124c..9cbc069 100644
--- a/dhcp-model.lua
+++ b/dhcp-model.lua
@@ -151,12 +151,23 @@ config_generate = function()
if #net.domainname.value > 0 then
tmpfile:write( " option domain-name \"" .. net.domainname.value .. "\";\n" )
end
- if #net.leaserangestart.value > 0 then
- tmpfile:write( " range " .. net.leaserangestart.value .. " " .. net.leaserangeend.value .. ";\n" )
- end
if #net.wpad.value > 0 then
tmpfile:write( " option local-wpad-server \"" .. net.wpad.value .. "\\n\";\n" )
end
+ spec2_msg = generate_pool( tmpfile, tmpfilename, net )
+ if #spec2_msg > 0 then
+ tmpfile:close()
+ os.remove( tmpfilename )
+ msg = "Configuration Generation Failed!\n\n" .. spec2_msg
+ return msg
+ end
+ spec2_msg = generate_hosts( tmpfile, tmpfilename, net )
+ if #spec2_msg > 0 then
+ tmpfile:close()
+ os.remove( tmpfilename )
+ msg = "Configuration Generation Failed!\n\n" .. spec2_msg
+ return msg
+ end
tmpfile:write( "}\n\n" )
end
@@ -168,62 +179,127 @@ config_generate = function()
return msg
end
- --- 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
+ tmpfile:close()
+ os.rename( tmpfilename, "/etc/dhcp/dhcpd.conf" )
+
+ return "Configuration Generation Successful!\n"
+end
+
+generate_pool = function( tmpfile, tmpfilename, net )
+ if not validator.is_ipv4( net.leaserangestart.value ) or
+ not validator.is_ipv4( net.leaserangeend.value ) then
+ if net.unknownclients.value == "permit" then
+ msg = "Reason: permitted unknown clients but failed to define lease range!\n"
+ return msg
+ end
+
+ return ""
+ end
+
+ --- pool header
+ tmpfile:write( " pool {\n" )
+ if net.unknownclients.value == "permit" then
+ tmpfile:write( " permit known clients;\n" )
+ tmpfile:write( " permit unknown clients;\n" )
+ else
+ tmpfile:write( " permit known clients;\n" )
+ tmpfile:write( " deny unknown clients;\n" )
+ end
+ tmpfile:write( " range " .. net.leaserangestart.value .. " " .. net.leaserangeend.value .. ";\n" )
+ tmpfile:write( " }\n" )
+
+ return ""
+end
+
+generate_hosts = function( tmpfile, tmpfilename, net )
+ --- generate static hosts
+ statichostsfile = io.open( cfgdir .. net.name.value .. ".static", "r" )
+ if statichostsfile ~= nil then
+ statichosts = statichostsfile:read( "*a" )
+ if statichosts == nil then
+ statichostsfile:close()
+ msg = "Configuration Generation Failed!\n\n" ..
+ "Reason: failed to read static hosts file for '" .. net.name.value .. "'"
+ return msg
+ end
+ msg = validate_statichosts( statichosts )
+ if #msg > 0 then
+ statichostsfile:close()
+ msg = "Configuration Generation Failed!\n\n" ..
+ "Reason: " .. msg
+ return msg
+ end
+
+ --- loop through all hosts
+ done = false
+ hosttoken = tokenizer.new( statichosts, "\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
- spechostsfile:close()
- tmpfile:write("}\n\n")
end
+ statichostsfile:close()
end
---
+
+ if net.unknownclients.value == "permit" then
+ return ""
+ end
+ --- generate dynamic hosts
+ dynamichostsfile = io.open( cfgdir .. net.name.value .. ".dynamic", "r" )
+ if dynamichostsfile ~= nil then
+ dynamichosts = dynamichostsfile:read( "*a" )
+ if dynamichosts == nil then
+ dynamichostsfile:close()
+ msg = "Configuration Generation Failed!\n\n" ..
+ "Reason: failed to read dynamic hosts file for '" .. net.name.value .. "'"
+ return msg
+ end
+ msg = validate_dynamichosts( dynamichosts )
+ if #msg > 0 then
+ dynamichostsfile:close()
+ msg = "Configuration Generation Failed!\n\n" ..
+ "Reason: " .. msg
+ return msg
+ end
- tmpfile:close()
- os.rename( tmpfilename, "/etc/dhcp/dhcpd.conf" )
+ --- loop through all hosts
+ done = false
+ hosttoken = tokenizer.new( dynamichosts, "\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, mac = tokenizer.next( spectoken )
+ spectoken, comment = tokenizer.next( spectoken )
+ tmpfile:write(" host " .. hostname .. " {\n")
+ tmpfile:write(" hardware ethernet " .. mac .. ";\n")
+ tmpfile:write(" }\n")
+ end
+ else
+ done = true
+ end
+ end
+ dynamichostsfile:close()
+ end
+ ---
- return "Configuration Generation Successful!\n"
+ return ""
end
subnet_delete = function( name )
@@ -232,14 +308,15 @@ subnet_delete = function( name )
local filename = cfgdir .. name
os.remove( filename .. ".subnet" )
- os.remove( filename .. ".spechosts" )
+ os.remove( filename .. ".static" )
+ os.remove( filename .. ".dynamic" )
return msg
end
subnet_read = function( name )
local filename = cfgdir .. name .. ".subnet"
- local net = create_new_net( name, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil )
+ local net = create_new_net( name, nil, nil, 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
@@ -264,17 +341,23 @@ subnet_read = function( name )
net.leaserangeend.value = string.sub(line, 18)
elseif (string.sub(line, 1, 5) == "wpad:") then
net.wpad.value = string.sub(line, 7)
+ elseif (string.sub(line, 1, 16) == "unknown-clients:") then
+ net.unknownclients.value = string.sub(line, 18)
end
end
+ if net.unknownclients.value ~= "permit" then
+ net.unknownclients.value = "deny"
+ end
- net.spechosts.value = subnet_get_spechosts( name )
+ net.statichosts.value = subnet_get_spechosts( name, "static" )
+ net.dynamichosts.value = subnet_get_spechosts( name, "dynamic" )
return net
end
-subnet_get_spechosts = function( name )
+subnet_get_spechosts = function( name, suffix )
local retval = ""
- local filename = cfgdir .. name .. ".spechosts"
+ local filename = cfgdir .. name .. "." .. suffix
if file_exists( filename ) then
local file = io.open( filename, "r" )
if file ~= nil then
@@ -289,15 +372,30 @@ subnet_get_spechosts = function( name )
return retval
end
-subnet_update_spechosts = function( name, spechosts )
+subnet_update_statichosts = function( name, statichosts )
+ local msg = "";
+ local filename = cfgdir .. name .. ".static"
+
+ file, errmsg = io.open( filename, "wb+" )
+ if file == nil then
+ msg = "Error: Failed to open " .. filename .. "(" .. errmsg .. ")!"
+ else
+ file:write( statichosts )
+ file:close()
+ end
+
+ return msg
+end
+
+subnet_update_dynamichosts = function( name, dynamichosts )
local msg = "";
- local filename = cfgdir .. name .. ".spechosts"
+ local filename = cfgdir .. name .. ".dynamic"
file, errmsg = io.open( filename, "wb+" )
if file == nil then
msg = "Error: Failed to open " .. filename .. "(" .. errmsg .. ")!"
else
- file:write( spechosts )
+ file:write( dynamichosts )
file:close()
end
@@ -340,27 +438,41 @@ subnet_write = function( net )
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:write( "unknown-clients: " .. net.unknownclients.value .. "\n" )
file:close()
- spec_msg = validate_spechosts( net.spechosts.value )
+
+ spec_msg = validate_statichosts( net.statichosts.value )
+ if #spec_msg == 0 then
+ spec_msg = subnet_update_statichosts( net.name.value, net.statichosts.value )
+ if #spec_msg > 0 then
+ msg = spec_msg
+ table.insert( fields, "statichosts" )
+ end
+ else
+ msg = spec_msg
+ table.insert( fields, "statichosts" )
+ end
+
+ spec_msg = validate_dynamichosts( net.dynamichosts.value )
if #spec_msg == 0 then
- spec_msg = subnet_update_spechosts( net.name.value, net.spechosts.value )
+ spec_msg = subnet_update_dynamichosts( net.name.value, net.dynamichosts.value )
if #spec_msg > 0 then
msg = spec_msg
- table.insert( fields, "spechosts" )
+ table.insert( fields, "dynamichosts" )
end
else
msg = spec_msg
- table.insert( fields, "spechosts" )
+ table.insert( fields, "dynamichosts" )
end
+
return cfe({ msg = msg, fields = {}}), net
end
-validate_spechosts = function( spechosts )
-
+validate_statichosts = function( statichosts )
local line = 1
local msg = ""
local done = false
- hosttoken = tokenizer.new( spechosts, "\n")
+ hosttoken = tokenizer.new( statichosts, "\n")
while not done do
hosttoken, nexthost = tokenizer.next( hosttoken )
if nexthost ~= nil then
@@ -371,24 +483,61 @@ validate_spechosts = function( spechosts )
fieldtoken, mac = tokenizer.next( fieldtoken )
fieldtoken, comment = tokenizer.next( fieldtoken )
if hostname == nil then
- msg = msg .. "hostname missing on line " .. line .. "!\n"
+ msg = msg .. "Static Hosts: hostname missing on line " .. line .. "!\n"
else
if not is_valid_hostname( hostname ) then
- msg = msg .. "Invalid hostname on line " .. line .. "!\n"
+ msg = msg .. "Static Hosts: Invalid hostname on line " .. line .. "!\n"
end
end
if ip == nil then
- msg = msg .. "ip missing on line " .. line .. "!\n"
+ msg = msg .. "Static Hosts: ip missing on line " .. line .. "!\n"
else
if not validator.is_ipv4( ip ) then
- msg = msg .. "Invalid ip on line " .. line .. "!\n"
+ msg = msg .. "Static Hosts: Invalid ip on line " .. line .. "!\n"
+ end
+ end
+ if mac == nil then
+ msg = msg .. "Static Hosts: mac missing on line " .. line .. "!\n"
+ else
+ if not validator.is_mac( mac ) then
+ msg = msg .. "Static Hosts: Invalid mac on line " .. line .. "!\n"
+ end
+ end
+ end
+ line = line + 1
+ else
+ done = true
+ end
+ end
+
+ return msg
+end
+
+validate_dynamichosts = function( dynamichosts )
+ local line = 1
+ local msg = ""
+ local done = false
+ hosttoken = tokenizer.new( dynamichosts, "\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, mac = tokenizer.next( fieldtoken )
+ fieldtoken, comment = tokenizer.next( fieldtoken )
+ if hostname == nil then
+ msg = msg .. "Static Hosts: hostname missing on line " .. line .. "!\n"
+ else
+ if not is_valid_hostname( hostname ) then
+ msg = msg .. "Static Hosts: Invalid hostname on line " .. line .. "!\n"
end
end
if mac == nil then
- msg = msg .. "mac missing on line " .. line .. "!\n"
+ msg = msg .. "Static Hosts: mac missing on line " .. line .. "!\n"
else
if not validator.is_mac( mac ) then
- msg = msg .. "Invalid mac on line " .. line .. "!\n"
+ msg = msg .. "Static Hosts: Invalid mac on line " .. line .. "!\n"
end
end
end
@@ -596,7 +745,7 @@ get_subnets = function ()
return retval
end
-create_new_net = function( name, defleasetime, maxleasetime, gateway, domainname, dnssrv1, dnssrv2, subnet, netmask, leaserangestart, leaserangeend, wpad, spechosts )
+create_new_net = function( name, defleasetime, maxleasetime, gateway, domainname, dnssrv1, dnssrv2, subnet, netmask, leaserangestart, leaserangeend, wpad, statichosts, unknownclients, dynamichosts )
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" },
@@ -609,8 +758,13 @@ create_new_net = function( name, defleasetime, maxleasetime, gateway, domainname
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="text" },
- spechosts = { label="Special Hosts Config", value=nonil(spechosts), type="text" }
+ statichosts = { label="Static Hosts", value=nonil(statichosts), type="text" },
+ dynamichosts = { label="Dynamic Hosts", value=nonil(dynamichosts), type="text" },
+ unknownclients = { label="Unknown Clients", value=nonil(unknownclients), type="text" }
}
+ if net.unknownclients.value ~= "permit" then
+ net.unknownclients.value = "deny"
+ end
return net
end