package config import ( "fmt" "net" ) type NetmapType string const ( NetmapDNAT NetmapType = "dnat" NetmapSNAT NetmapType = "snat" ) // Netmap maps addresses in one network to corresponding addresses in another. // For DNAT: traffic entering the interface addressed to Net1 has its dest rewritten to Net2. // For SNAT: traffic leaving the interface with source in Net1 has its source rewritten to Net2. type Netmap struct { Type NetmapType `yaml:"type"` // Network in CIDR format to match. Net1 string `yaml:"net1"` // Interface name (must be defined in interfaces). Interface string `yaml:"interface"` // Network in CIDR format to rewrite to. Net2 string `yaml:"net2"` // Optional qualifying network: source for DNAT rules, destination for SNAT rules. Net3 string `yaml:"net3,omitempty"` Proto string `yaml:"proto,omitempty"` DPort PortSpec `yaml:"dport,omitempty"` SPort PortSpec `yaml:"sport,omitempty"` Comment string `yaml:"comment,omitempty"` } func (c *Config) validateNetmap() error { for i, nm := range c.Netmap { switch nm.Type { case NetmapDNAT, NetmapSNAT: default: return fmt.Errorf("netmap[%d]: type must be dnat or snat, got %q", i, nm.Type) } if nm.Net1 == "" { return fmt.Errorf("netmap[%d]: net1 required", i) } if _, _, err := net.ParseCIDR(nm.Net1); err != nil { return fmt.Errorf("netmap[%d]: net1 must be CIDR format: %w", i, err) } if nm.Interface == "" { return fmt.Errorf("netmap[%d]: interface required", i) } ifaceFound := false for _, iface := range c.Interfaces { if iface.Interface == nm.Interface || iface.PhysicalName() == nm.Interface { ifaceFound = true break } } if !ifaceFound { return fmt.Errorf("netmap[%d]: interface %q not defined in interfaces", i, nm.Interface) } if nm.Net2 == "" { return fmt.Errorf("netmap[%d]: net2 required", i) } if _, _, err := net.ParseCIDR(nm.Net2); err != nil { return fmt.Errorf("netmap[%d]: net2 must be CIDR format: %w", i, err) } if nm.Net3 != "" { if _, _, err := net.ParseCIDR(nm.Net3); err != nil { return fmt.Errorf("netmap[%d]: net3 must be CIDR format: %w", i, err) } } } return nil }