ntopng/scripts/lua/modules/conf_handlers/isc_dhcp_server.lua
2026-01-19 16:23:53 +01:00

128 lines
4.6 KiB
Lua

--
-- (C) 2013-26 - ntop.org
--
local sys_utils = require "sys_utils"
local isc_dhcp_server = {}
-- ###############################################################
-- Writes the ISC DHCP server configuration files
-- @param dhcp_config The DHCP server configuration table
-- @param all_interfaces Table mapping interface names to roles (lan/wan)
-- @param dns_config The DNS configuration table with global and secondary DNS
-- @return true on success, false on error
function isc_dhcp_server.writeDhcpServerConfiguration(dhcp_config, all_interfaces, dns_config)
if not dhcp_config or not all_interfaces or not dns_config then
traceError(TRACE_ERROR, TRACE_CONSOLE, "Invalid parameters for writeDhcpServerConfiguration")
return false
end
local lan_interfaces = ""
local count = 0
-- Create the string for the isc-dhcp-server.
-- It has to be like: INTERFACES=" eno1.11 eno1.12"
for if_name, role in pairsByKeys(all_interfaces, asc_insensitive) do
if (role == "lan") and (dhcp_config["subnet"][if_name]) and (dhcp_config["subnet"][if_name]["enabled"] == "1") then
-- To not place the space at the start of the string
if count == 0 then
lan_interfaces = if_name
count = 1
else
lan_interfaces = lan_interfaces .. " " .. if_name
end
end
end
-- Write the isc-dhcp-server file
local f = sys_utils.openFile("/etc/default/isc-dhcp-server", "w")
if not f then
traceError(TRACE_ERROR, TRACE_CONSOLE, "Cannot open /etc/default/isc-dhcp-server for writing")
return false
end
f:write("INTERFACES=\""..lan_interfaces.."\"\n")
f:close()
-- Now modify the dhcpd.conf file
f = sys_utils.openFile("/etc/dhcp/dhcpd.conf", "w")
if not f then
traceError(TRACE_ERROR, TRACE_CONSOLE, "Cannot open /etc/dhcp/dhcpd.conf for writing")
return false
end
for _, opt in ipairs(dhcp_config.options) do
f:write(opt .. ";\n")
end
local configure_option_114 = false
local configure_option_160 = false
for if_name, role in pairsByKeys(all_interfaces, asc_insensitive) do
local lan_dhcp_config = dhcp_config["subnet"][if_name]
if (role == "lan") and (lan_dhcp_config) and (dhcp_config["subnet"][if_name]["enabled"] == "1") then
if not isEmptyString(lan_dhcp_config["option_114"]) then
configure_option_114 = true
end
if not isEmptyString(lan_dhcp_config["option_160"]) then
configure_option_160 = true
end
end
end
if configure_option_114 then
f:write("option option-114 code 114 = text;\n")
end
if configure_option_160 then
f:write("option option-160 code 160 = text;\n")
end
-- Each LAN interfaces needs a different DHCP, so iterate all the LAN interfaces
-- and update the configuration from the one added in the GUI
-- IMPORTANT NOTE: in the dhcp_config.subnet configuration ALL the interfaces are present
-- for this reason we need a check on the LAN here
for if_name, role in pairsByKeys(all_interfaces, asc_insensitive) do
local lan_dhcp_config = dhcp_config["subnet"][if_name]
if (role == "lan") and (lan_dhcp_config) and (dhcp_config["subnet"][if_name]["enabled"] == "1") then
f:write("\n")
f:write("subnet ".. lan_dhcp_config["network"] .." netmask ".. lan_dhcp_config["netmask"] .." {\n")
f:write(" range " .. lan_dhcp_config["first_ip"] .. " " .. lan_dhcp_config["last_ip"] .. ";\n")
f:write(" option domain-name-servers " .. table.concat({
dns_config.global,
ternary(not isEmptyString(dns_config.secondary), dns_config.secondary, nil)
},", ") .. ";\n")
f:write(" option routers " .. lan_dhcp_config["gateway"] .. ";\n")
f:write(" option subnet-mask ".. lan_dhcp_config["netmask"] ..";\n")
f:write(" option broadcast-address " .. lan_dhcp_config["broadcast"] .. ";\n")
-- Write all the extra options
for _, opt in ipairs(lan_dhcp_config["options"] or {}) do
f:write(" " .. opt .. ";\n")
end
if not isEmptyString(lan_dhcp_config["option_114"]) then
f:write(" option option-114 \"" .. lan_dhcp_config["option_114"] .. "\";\n")
end
if not isEmptyString(lan_dhcp_config["option_160"]) then
f:write(" option option-160 \"" .. lan_dhcp_config["option_160"] .. "\";\n")
end
f:write("}\n")
end
end
for mac, lease in pairs(dhcp_config.leases) do
f:write("\n")
f:write("host " .. lease.hostname .. " {\n")
f:write(" hardware ethernet " .. mac .. ";\n")
f:write(" fixed-address " .. lease.ip .. ";\n")
f:write("}\n")
end
f:close()
return true
end
-- ###############################################################
return isc_dhcp_server