71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
type Host struct {
|
|
Zone string `yaml:"zone"`
|
|
Interface string `yaml:"interface"`
|
|
Addresses []string `yaml:"addresses"`
|
|
Exclusions []string `yaml:"exclusions,omitempty"`
|
|
Dynamic bool `yaml:"dynamic,omitempty"`
|
|
Options HostOptions `yaml:"options,omitempty"`
|
|
}
|
|
|
|
type HostOptions struct {
|
|
Broadcast bool `yaml:"broadcast,omitempty"`
|
|
DestOnly bool `yaml:"destonly,omitempty"`
|
|
IPSec bool `yaml:"ipsec,omitempty"`
|
|
MSS int `yaml:"mss,omitempty"`
|
|
NoSmurfs bool `yaml:"nosmurfs,omitempty"`
|
|
RouteBack bool `yaml:"routeback,omitempty"`
|
|
TCPFlags bool `yaml:"tcpflags,omitempty"`
|
|
}
|
|
|
|
func (c *Config) validateHosts() error {
|
|
fwZone := c.FirewallZone()
|
|
|
|
for i, h := range c.Hosts {
|
|
if h.Zone == "" {
|
|
return fmt.Errorf("host[%d]: zone required", i)
|
|
}
|
|
if h.Zone == fwZone {
|
|
return fmt.Errorf("host[%d]: firewall zone must not be listed in hosts", i)
|
|
}
|
|
if _, ok := c.Zones[h.Zone]; !ok {
|
|
return fmt.Errorf("host[%d]: zone %q not defined", i, h.Zone)
|
|
}
|
|
if h.Interface == "" {
|
|
return fmt.Errorf("host[%d]: interface required", i)
|
|
}
|
|
|
|
ifaceFound := false
|
|
for _, iface := range c.Interfaces {
|
|
prefix, wild := strings.CutSuffix(iface.PhysicalName(), "+")
|
|
if iface.Interface == h.Interface || iface.PhysicalName() == h.Interface || (wild && strings.HasPrefix(h.Interface, prefix)) {
|
|
ifaceFound = true
|
|
break
|
|
}
|
|
}
|
|
if !ifaceFound {
|
|
return fmt.Errorf("host[%d]: interface %q not defined in interfaces", i, h.Interface)
|
|
}
|
|
|
|
if !h.Dynamic && len(h.Addresses) == 0 {
|
|
return fmt.Errorf("host[%d]: at least one address required (or set dynamic: true)", i)
|
|
}
|
|
for _, a := range slices.Concat(h.Addresses, h.Exclusions) {
|
|
if _, err := netip.ParsePrefix(a); err != nil {
|
|
if _, err := netip.ParseAddr(a); err != nil {
|
|
return fmt.Errorf("host[%d]: invalid address %q", i, a)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|