-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Licensed to the public under the Apache License 2.0.
-local sys = require "luci.sys"
+local ipc = require "luci.ip"
+local o
+require "luci.util"
m = Map("dhcp", translate("DHCP and DNS"),
translate("Dnsmasq is a combined <abbr title=\"Dynamic Host Configuration Protocol" ..
s:taboption("files", Flag, "nohosts",
- translate("Ignore Hosts files")).optional = true
+ translate("Ignore <code>/etc/hosts</code>")).optional = true
-hf = s:taboption("files", DynamicList, "addnhosts",
- translate("Additional Hosts files"))
+s:taboption("files", DynamicList, "addnhosts",
+ translate("Additional Hosts files")).optional = true
-hf:depends("nohosts", "")
-hf.optional = true
+qu = s:taboption("advanced", Flag, "quietdhcp",
+ translate("Suppress logging"),
+ translate("Suppress logging of the routine operation of these protocols"))
+qu.optional = true
+se = s:taboption("advanced", Flag, "sequential_ip",
+ translate("Allocate IP sequentially"),
+ translate("Allocate IP addresses sequentially, starting from the lowest available address"))
+se.optional = true
s:taboption("advanced", Flag, "boguspriv",
translate("Filter private"),
translate("Localise queries"),
translate("Localise hostname depending on the requesting subnet if multiple IPs are available"))
+local have_dnssec_support = luci.util.checklib("/usr/sbin/dnsmasq", "libhogweed.so")
+
+if have_dnssec_support then
+ o = s:taboption("advanced", Flag, "dnssec",
+ translate("DNSSEC"))
+ o.optional = true
+
+ o = s:taboption("advanced", Flag, "dnsseccheckunsigned",
+ translate("DNSSEC check unsigned"),
+ translate("Requires upstream supports DNSSEC; verify unsigned domain responses really come from unsigned domains"))
+ o.optional = true
+end
+
s:taboption("general", Value, "local",
translate("Local server"),
translate("Local domain specification. Names matching this domain are never forwarded and are resolved from DHCP or hosts files only"))
translate("No negative cache"),
translate("Do not cache negative replies, e.g. for not existing domains"))
+s:taboption("advanced", Value, "serversfile",
+ translate("Additional servers file"),
+ translate("This file may contain lines like 'server=/domain/1.2.3.4' or 'server=1.2.3.4' for"..
+ "domain-specific or full upstream <abbr title=\"Domain Name System\">DNS</abbr> servers."))
+
s:taboption("advanced", Flag, "strictorder",
translate("Strict order"),
translate("<abbr title=\"Domain Name System\">DNS</abbr> servers will be queried in the " ..
rd = s:taboption("general", DynamicList, "rebind_domain",
translate("Domain whitelist"),
translate("List of domains to allow RFC1918 responses for"))
+rd.optional = true
rd:depends("rebind_protection", "1")
-rd.datatype = "host"
+rd.datatype = "host(1)"
rd.placeholder = "ihost.netflix.com"
db:depends("enable_tftp", "1")
db.placeholder = "pxelinux.0"
+o = s:taboption("general", Flag, "localservice",
+ translate("Local Service Only"),
+ translate("Limit DNS service to subnets interfaces on which we are serving DNS."))
+o.optional = false
+o.rmempty = false
+
+o = s:taboption("general", Flag, "nonwildcard",
+ translate("Non-wildcard"),
+ translate("Bind only to specific interfaces rather than wildcard address."))
+o.optional = false
+o.rmempty = false
+
+o = s:taboption("general", DynamicList, "interface",
+ translate("Listen Interfaces"),
+ translate("Limit listening to these interfaces, and loopback."))
+o.optional = true
+o:depends("nonwildcard", true)
+
+o = s:taboption("general", DynamicList, "notinterface",
+ translate("Exclude interfaces"),
+ translate("Prevent listening on thise interfaces."))
+o.optional = true
+o:depends("nonwildcard", true)
m:section(SimpleSection).template = "admin_network/lease_status"
"only hosts with a corresponding lease are served.") .. "<br />" ..
translate("Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</em> " ..
"indentifies the host, the <em>IPv4-Address</em> specifies to the fixed address to " ..
- "use and the <em>Hostname</em> is assigned as symbolic name to the requesting host."))
+ "use and the <em>Hostname</em> is assigned as symbolic name to the requesting host. " ..
+ "The optional <em>Lease time</em> can be used to set non-standard host-specific " ..
+ "lease time, e.g. 12h, 3d or infinite."))
s.addremove = true
s.anonymous = true
ip = s:option(Value, "ip", translate("<abbr title=\"Internet Protocol Version 4\">IPv4</abbr>-Address"))
ip.datatype = "or(ip4addr,'ignore')"
+time = s:option(Value, "leasetime", translate("Lease time"))
+time.rmempty = true
+
hostid = s:option(Value, "hostid", translate("<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"))
-sys.net.arptable(function(entry)
- ip:value(entry["IP address"])
- mac:value(
- entry["HW address"],
- entry["HW address"] .. " (" .. entry["IP address"] .. ")"
- )
+ipc.neighbors({ family = 4 }, function(n)
+ if n.mac and n.dest then
+ ip:value(n.dest:string())
+ mac:value(n.mac, "%s (%s)" %{ n.mac, n.dest:string() })
+ end
end)
function ip.validate(self, value, section)