diff --git a/cli.go b/cli.go index 7926170..a9edf9d 100644 --- a/cli.go +++ b/cli.go @@ -225,7 +225,7 @@ func (c *Config) setRedundantOptions() { } } -//nolint:forbidigo,maintidx,gocognit +//nolint:forbidigo,maintidx,gocognit,gocyclo func configFromCLI() (config *Config, logger *Logger, err error) { var ( interfaceName string @@ -407,6 +407,8 @@ func configFromCLI() (config *Config, logger *Logger, err error) { if config.RelayIPv6 == nil && config.RelayIPv4 == nil { return config, logger, fmt.Errorf("no relay IP configured: %s and %s", errIPv4, errIPv6) //nolint:errorlint + } else if errIPv6 != nil && config.Verbose { + logger.Errorf("Warning: could not auto-detect relay IPv6 address: %v", err) } config.LocalIPv6, err = getLinkLocalIPv6Address(config.Interface) diff --git a/dhcpv6.go b/dhcpv6.go index 1240290..e9ab2b6 100644 --- a/dhcpv6.go +++ b/dhcpv6.go @@ -10,6 +10,8 @@ import ( "strings" "time" + cryptoRand "crypto/rand" + "github.com/insomniacslk/dhcp/dhcpv6" "github.com/insomniacslk/dhcp/dhcpv6/server6" "github.com/insomniacslk/dhcp/iana" @@ -42,14 +44,37 @@ type DHCPv6Handler struct { // NewDHCPv6Handler returns a DHCPv6Handler. func NewDHCPv6Handler(config *Config, logger *Logger) *DHCPv6Handler { - return &DHCPv6Handler{ + handler := &DHCPv6Handler{ logger: logger, config: config, - serverID: &dhcpv6.DUIDLL{ + } + + if config.Interface.HardwareAddr != nil { + handler.serverID = &dhcpv6.DUIDLL{ HWType: iana.HWTypeEthernet, LinkLayerAddr: config.Interface.HardwareAddr, - }, + } + } else { + handler.serverID = &dhcpv6.DUIDUUID{ + UUID: generateUUID(), + } } + + return handler +} + +func generateUUID() (uuid [16]byte) { + _, err := cryptoRand.Read(uuid[:]) + if err != nil { + panic(err) + } + + // Set version to 4 (random) + uuid[6] = (uuid[6] & 0x0f) | 0x40 //nolint:mnd + // Set variant to RFC 4122 + uuid[8] = (uuid[8] & 0x3f) | 0x80 //nolint:mnd + + return uuid } // Handler implements a server6.Handler. diff --git a/router_advertisement.go b/router_advertisement.go index cc39aab..bb50652 100644 --- a/router_advertisement.go +++ b/router_advertisement.go @@ -133,12 +133,13 @@ func sendRouterAdvertisement(c *ndp.Conn, receiver netip.Addr, stateless bool, r RouterSelectionPreference: ndp.High, RouterLifetime: routerLifetime, - Options: []ndp.Option{ - &ndp.LinkLayerAddress{ - Direction: ndp.Source, - Addr: routerMAC, - }, - }, + } + + if len(routerMAC) == 0 { + raMessage.Options = append(raMessage.Options, &ndp.LinkLayerAddress{ + Direction: ndp.Source, + Addr: routerMAC, + }) } if dnsAddr != nil {