Files
router/tools/ipadm/host.go
T
mike 8591223aca ipadm: Port-Forwarding hinzufügen (-pa/-pl/-pd) + nftables-Include verdrahten
- ipadm verwaltet jetzt auch WAN->LAN Port-Forwards, referenziert per
  Hostname aus der bestehenden Host-DB (folgt IP-Änderungen automatisch)
- ipadm -u generiert zusätzlich /etc/nftables.d/portforward.conf, validiert
  via 'nft -c -f' und reloadet nftables (Rollback bei ungültiger Config,
  wie beim dnsmasq-Teil)
- /etc/nftables.conf bindet dafür neu /etc/nftables.d/*.conf ein
- Host-Store-Locking-Logik in generischen LineStore[T] extrahiert, von
  Host- und PortForward-Store gemeinsam genutzt
2026-08-18 11:43:29 +02:00

85 lines
1.8 KiB
Go

package main
import (
"fmt"
"sort"
"strings"
)
// Host is one static host entry: hostname, IP, optional MAC, free-text comment.
type Host struct {
Name string
IP string
MAC string // "" if not set
Comment string
}
const hostHeader = "# ipadm host database - managed with `ipadm`, do not edit while ipadm is running\n" +
"# name\tip\tmac\tcomment\n"
// One line per host, tab-separated: name\tip\tmac\tcomment
// MAC is stored as "-" when empty.
func parseHostLine(line string) (Host, error) {
parts := strings.SplitN(line, "\t", 4)
if len(parts) < 3 {
return Host{}, fmt.Errorf("ungültige Zeile (erwarte mind. 3 Tab-getrennte Felder): %q", line)
}
mac := parts[2]
if mac == "-" {
mac = ""
}
comment := ""
if len(parts) == 4 {
comment = parts[3]
}
return Host{Name: parts[0], IP: parts[1], MAC: mac, Comment: comment}, nil
}
func formatHostLine(h Host) string {
mac := h.MAC
if mac == "" {
mac = "-"
}
return fmt.Sprintf("%s\t%s\t%s\t%s", h.Name, h.IP, mac, h.Comment)
}
func openHostStore(path string) (*LineStore[Host], error) {
return openLineStore(path, hostHeader, parseHostLine, formatHostLine)
}
func sortHosts(hosts []Host) {
sort.Slice(hosts, func(i, j int) bool {
return strings.ToLower(hosts[i].Name) < strings.ToLower(hosts[j].Name)
})
}
func findHost(hosts []Host, name string) int {
for i, h := range hosts {
if strings.EqualFold(h.Name, name) {
return i
}
}
return -1
}
func findByIP(hosts []Host, ip string, exceptIdx int) int {
for i, h := range hosts {
if i != exceptIdx && h.IP == ip {
return i
}
}
return -1
}
func findByMAC(hosts []Host, mac string, exceptIdx int) int {
if mac == "" {
return -1
}
for i, h := range hosts {
if i != exceptIdx && h.MAC != "" && strings.EqualFold(h.MAC, mac) {
return i
}
}
return -1
}