|
|
@@ -147,8 +147,8 @@ func (sm *ServerManager) saveLocked() error {
|
|
|
func (sm *ServerManager) applyDnsmasqConfigLocked() error {
|
|
|
var sb strings.Builder
|
|
|
sb.WriteString("# ==================================================================\n")
|
|
|
- sb.WriteString("# DebTik DHCP Server Configuration (MikroTik RouterOS style)\n")
|
|
|
- sb.WriteString("# Auto-generated by DebTik Network Appliance. DO NOT EDIT DIRECTLY.\n")
|
|
|
+ sb.WriteString("# Enterprise DHCP Server Configuration\n")
|
|
|
+ sb.WriteString("# Auto-generated by Network Appliance. DO NOT EDIT DIRECTLY.\n")
|
|
|
sb.WriteString("# ==================================================================\n\n")
|
|
|
|
|
|
sb.WriteString("dhcp-authoritative\n")
|
|
|
@@ -171,8 +171,28 @@ func (sm *ServerManager) applyDnsmasqConfigLocked() error {
|
|
|
leaseTime = "12h"
|
|
|
}
|
|
|
|
|
|
+ // Find assigned network for server
|
|
|
+ var assignedNet *DHCPNetwork
|
|
|
+ if srv.Network != "" {
|
|
|
+ for _, n := range sm.networks {
|
|
|
+ if n.Address == srv.Network || n.ID == srv.Network {
|
|
|
+ copyN := n
|
|
|
+ assignedNet = ©N
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// Parse Address Pool range (e.g. 192.168.88.10-192.168.88.254)
|
|
|
startIP, endIP, netmask := parseAddressPool(srv.AddressPool)
|
|
|
+ if netmask == "" && assignedNet != nil {
|
|
|
+ if assignedNet.Netmask != "" {
|
|
|
+ netmask = assignedNet.Netmask
|
|
|
+ } else if _, ipNet, err := net.ParseCIDR(assignedNet.Address); err == nil && ipNet != nil {
|
|
|
+ netmask = net.IP(ipNet.Mask).String()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if startIP != "" && endIP != "" {
|
|
|
if netmask != "" {
|
|
|
sb.WriteString(fmt.Sprintf("dhcp-range=set:%s,interface:%s,%s,%s,%s,%s\n", tag, srv.Interface, startIP, endIP, netmask, leaseTime))
|
|
|
@@ -180,11 +200,48 @@ func (sm *ServerManager) applyDnsmasqConfigLocked() error {
|
|
|
sb.WriteString(fmt.Sprintf("dhcp-range=set:%s,interface:%s,%s,%s,%s\n", tag, srv.Interface, startIP, endIP, leaseTime))
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // Emit assigned network options specifically for this DHCP server tag
|
|
|
+ if assignedNet != nil {
|
|
|
+ targetTag := fmt.Sprintf("tag:%s,", tag)
|
|
|
+
|
|
|
+ if assignedNet.Gateway != "" {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%soption:router,%s\n", targetTag, assignedNet.Gateway))
|
|
|
+ }
|
|
|
+ if len(assignedNet.DNSServers) > 0 {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%soption:dns-server,%s\n", targetTag, strings.Join(assignedNet.DNSServers, ",")))
|
|
|
+ }
|
|
|
+ if assignedNet.Domain != "" {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%soption:domain-name,%s\n", targetTag, assignedNet.Domain))
|
|
|
+ }
|
|
|
+ if len(assignedNet.NTPServers) > 0 {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%soption:ntp-server,%s\n", targetTag, strings.Join(assignedNet.NTPServers, ",")))
|
|
|
+ }
|
|
|
+ if assignedNet.NextServer != "" {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%soption:tftp-server,%s\n", targetTag, assignedNet.NextServer))
|
|
|
+ }
|
|
|
+ if assignedNet.BootFileName != "" {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%soption:bootfile-name,%s\n", targetTag, assignedNet.BootFileName))
|
|
|
+ if assignedNet.NextServer != "" {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-boot=%s%s,,%s\n", targetTag, assignedNet.BootFileName, assignedNet.NextServer))
|
|
|
+ } else {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-boot=%s%s\n", targetTag, assignedNet.BootFileName))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(assignedNet.WINSServers) > 0 {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%soption:netbios-ns,%s\n", targetTag, strings.Join(assignedNet.WINSServers, ",")))
|
|
|
+ }
|
|
|
+ for _, optID := range assignedNet.DHCPOptions {
|
|
|
+ if opt, exists := sm.options[optID]; exists {
|
|
|
+ sb.WriteString(fmt.Sprintf("dhcp-option=%s%d,%s # %s\n", targetTag, opt.Code, opt.Value, opt.Name))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
sb.WriteString("\n")
|
|
|
}
|
|
|
|
|
|
- // Subnet Networks & Options
|
|
|
- sb.WriteString("# --- DHCP Networks & Options (/ip dhcp-server network) ---\n")
|
|
|
+ // Subnet Networks & Options (Fallback and IP-matching)
|
|
|
+ sb.WriteString("# --- Subnet Networks Fallbacks & IP matching ---\n")
|
|
|
for _, netw := range sm.networks {
|
|
|
sb.WriteString(fmt.Sprintf("# Subnet: %s\n", netw.Address))
|
|
|
_, ipNet, err := net.ParseCIDR(netw.Address)
|
|
|
@@ -250,8 +307,8 @@ func (sm *ServerManager) applyDnsmasqConfigLocked() error {
|
|
|
sb.WriteString("\n")
|
|
|
}
|
|
|
|
|
|
- // Static Leases & Reservations (/ip dhcp-server lease)
|
|
|
- sb.WriteString("# --- Static Leases & Reservations (/ip dhcp-server lease) ---\n")
|
|
|
+ // Static Leases & Reservations
|
|
|
+ sb.WriteString("# --- Static Leases & Reservations ---\n")
|
|
|
for _, l := range sm.staticLeases {
|
|
|
if l.Disabled {
|
|
|
continue
|
|
|
@@ -714,6 +771,7 @@ func (sm *ServerManager) RunSetupWizard(req DHCPServerSetupRequest) error {
|
|
|
ID: srvID,
|
|
|
Name: fmt.Sprintf("dhcp-%s", req.Interface),
|
|
|
Interface: req.Interface,
|
|
|
+ Network: req.AddressSpace,
|
|
|
AddressPool: req.AddressPool,
|
|
|
LeaseTime: req.LeaseTime,
|
|
|
Authoritative: true,
|