// Copyright 2019 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package header

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"math"
	"time"

	"gvisor.dev/gvisor/pkg/tcpip"
)

// ndpOptionIdentifier is an NDP option type identifier.
type ndpOptionIdentifier uint8

const (
	// ndpSourceLinkLayerAddressOptionType is the type of the Source Link Layer
	// Address option, as per RFC 4861 section 4.6.1.
	ndpSourceLinkLayerAddressOptionType ndpOptionIdentifier = 1

	// ndpTargetLinkLayerAddressOptionType is the type of the Target Link Layer
	// Address option, as per RFC 4861 section 4.6.1.
	ndpTargetLinkLayerAddressOptionType ndpOptionIdentifier = 2

	// ndpPrefixInformationType is the type of the Prefix Information
	// option, as per RFC 4861 section 4.6.2.
	ndpPrefixInformationType ndpOptionIdentifier = 3

	// ndpNonceOptionType is the type of the Nonce option, as per
	// RFC 3971 section 5.3.2.
	ndpNonceOptionType ndpOptionIdentifier = 14

	// ndpRecursiveDNSServerOptionType is the type of the Recursive DNS
	// Server option, as per RFC 8106 section 5.1.
	ndpRecursiveDNSServerOptionType ndpOptionIdentifier = 25

	// ndpDNSSearchListOptionType is the type of the DNS Search List option,
	// as per RFC 8106 section 5.2.
	ndpDNSSearchListOptionType ndpOptionIdentifier = 31
)

const (
	// NDPLinkLayerAddressSize is the size of a Source or Target Link Layer
	// Address option for an Ethernet address.
	NDPLinkLayerAddressSize = 8

	// ndpPrefixInformationLength is the expected length, in bytes, of the
	// body of an NDP Prefix Information option, as per RFC 4861 section
	// 4.6.2 which specifies that the Length field is 4. Given this, the
	// expected length, in bytes, is 30 becuase 4 * lengthByteUnits (8) - 2
	// (Type & Length) = 30.
	ndpPrefixInformationLength = 30

	// ndpPrefixInformationPrefixLengthOffset is the offset of the Prefix
	// Length field within an NDPPrefixInformation.
	ndpPrefixInformationPrefixLengthOffset = 0

	// ndpPrefixInformationFlagsOffset is the offset of the flags byte
	// within an NDPPrefixInformation.
	ndpPrefixInformationFlagsOffset = 1

	// ndpPrefixInformationOnLinkFlagMask is the mask of the On-Link Flag
	// field in the flags byte within an NDPPrefixInformation.
	ndpPrefixInformationOnLinkFlagMask = (1 << 7)

	// ndpPrefixInformationAutoAddrConfFlagMask is the mask of the
	// Autonomous Address-Configuration flag field in the flags byte within
	// an NDPPrefixInformation.
	ndpPrefixInformationAutoAddrConfFlagMask = (1 << 6)

	// ndpPrefixInformationReserved1FlagsMask is the mask of the Reserved1
	// field in the flags byte within an NDPPrefixInformation.
	ndpPrefixInformationReserved1FlagsMask = 63

	// ndpPrefixInformationValidLifetimeOffset is the start of the 4-byte
	// Valid Lifetime field within an NDPPrefixInformation.
	ndpPrefixInformationValidLifetimeOffset = 2

	// ndpPrefixInformationPreferredLifetimeOffset is the start of the
	// 4-byte Preferred Lifetime field within an NDPPrefixInformation.
	ndpPrefixInformationPreferredLifetimeOffset = 6

	// ndpPrefixInformationReserved2Offset is the start of the 4-byte
	// Reserved2 field within an NDPPrefixInformation.
	ndpPrefixInformationReserved2Offset = 10

	// ndpPrefixInformationReserved2Length is the length of the Reserved2
	// field.
	//
	// It is 4 bytes.
	ndpPrefixInformationReserved2Length = 4

	// ndpPrefixInformationPrefixOffset is the start of the Prefix field
	// within an NDPPrefixInformation.
	ndpPrefixInformationPrefixOffset = 14

	// ndpRecursiveDNSServerLifetimeOffset is the start of the 4-byte
	// Lifetime field within an NDPRecursiveDNSServer.
	ndpRecursiveDNSServerLifetimeOffset = 2

	// ndpRecursiveDNSServerAddressesOffset is the start of the addresses
	// for IPv6 Recursive DNS Servers within an NDPRecursiveDNSServer.
	ndpRecursiveDNSServerAddressesOffset = 6

	// minNDPRecursiveDNSServerLength is the minimum NDP Recursive DNS Server
	// option's body size when it contains at least one IPv6 address, as per
	// RFC 8106 section 5.3.1.
	minNDPRecursiveDNSServerBodySize = 22

	// ndpDNSSearchListLifetimeOffset is the start of the 4-byte
	// Lifetime field within an NDPDNSSearchList.
	ndpDNSSearchListLifetimeOffset = 2

	// ndpDNSSearchListDomainNamesOffset is the start of the DNS search list
	// domain names within an NDPDNSSearchList.
	ndpDNSSearchListDomainNamesOffset = 6

	// minNDPDNSSearchListBodySize is the minimum NDP DNS Search List option's
	// body size when it contains at least one domain name, as per RFC 8106
	// section 5.3.1.
	minNDPDNSSearchListBodySize = 14

	// maxDomainNameLabelLength is the maximum length of a domain name
	// label, as per RFC 1035 section 3.1.
	maxDomainNameLabelLength = 63

	// maxDomainNameLength is the maximum length of a domain name, including
	// label AND label length octet, as per RFC 1035 section 3.1.
	maxDomainNameLength = 255

	// lengthByteUnits is the multiplier factor for the Length field of an
	// NDP option. That is, the length field for NDP options is in units of
	// 8 octets, as per RFC 4861 section 4.6.
	lengthByteUnits = 8
)

var (
	// NDPInfiniteLifetime is a value that represents infinity for the
	// 4-byte lifetime fields found in various NDP options. Its value is
	// (2^32 - 1)s = 4294967295s.
	//
	// This is a variable instead of a constant so that tests can change
	// this value to a smaller value. It should only be modified by tests.
	NDPInfiniteLifetime = time.Second * math.MaxUint32
)

// NDPOptionIterator is an iterator of NDPOption.
//
// Note, between when an NDPOptionIterator is obtained and last used, no changes
// to the NDPOptions may happen. Doing so may cause undefined and unexpected
// behaviour. It is fine to obtain an NDPOptionIterator, iterate over the first
// few NDPOption then modify the backing NDPOptions so long as the
// NDPOptionIterator obtained before modification is no longer used.
type NDPOptionIterator struct {
	opts *bytes.Buffer
}

// Potential errors when iterating over an NDPOptions.
var (
	ErrNDPOptMalformedBody   = errors.New("NDP option has a malformed body")
	ErrNDPOptMalformedHeader = errors.New("NDP option has a malformed header")
)

// Next returns the next element in the backing NDPOptions, or true if we are
// done, or false if an error occured.
//
// The return can be read as option, done, error. Note, option should only be
// used if done is false and error is nil.
func (i *NDPOptionIterator) Next() (NDPOption, bool, error) {
	for {
		// Do we still have elements to look at?
		if i.opts.Len() == 0 {
			return nil, true, nil
		}

		// Get the Type field.
		temp, err := i.opts.ReadByte()
		if err != nil {
			if err != io.EOF {
				// ReadByte should only ever return nil or io.EOF.
				panic(fmt.Sprintf("unexpected error when reading the option's Type field: %s", err))
			}

			// We use io.ErrUnexpectedEOF as exhausting the buffer is unexpected once
			// we start parsing an option; we expect the buffer to contain enough
			// bytes for the whole option.
			return nil, true, fmt.Errorf("unexpectedly exhausted buffer when reading the option's Type field: %w", io.ErrUnexpectedEOF)
		}
		kind := ndpOptionIdentifier(temp)

		// Get the Length field.
		length, err := i.opts.ReadByte()
		if err != nil {
			if err != io.EOF {
				panic(fmt.Sprintf("unexpected error when reading the option's Length field for %s: %s", kind, err))
			}

			return nil, true, fmt.Errorf("unexpectedly exhausted buffer when reading the option's Length field for %s: %w", kind, io.ErrUnexpectedEOF)
		}

		// This would indicate an erroneous NDP option as the Length field should
		// never be 0.
		if length == 0 {
			return nil, true, fmt.Errorf("zero valued Length field for %s: %w", kind, ErrNDPOptMalformedHeader)
		}

		// Get the body.
		numBytes := int(length) * lengthByteUnits
		numBodyBytes := numBytes - 2
		body := i.opts.Next(numBodyBytes)
		if len(body) < numBodyBytes {
			return nil, true, fmt.Errorf("unexpectedly exhausted buffer when reading the option's Body for %s: %w", kind, io.ErrUnexpectedEOF)
		}

		switch kind {
		case ndpSourceLinkLayerAddressOptionType:
			return NDPSourceLinkLayerAddressOption(body), false, nil

		case ndpTargetLinkLayerAddressOptionType:
			return NDPTargetLinkLayerAddressOption(body), false, nil

		case ndpNonceOptionType:
			return NDPNonceOption(body), false, nil

		case ndpPrefixInformationType:
			// Make sure the length of a Prefix Information option
			// body is ndpPrefixInformationLength, as per RFC 4861
			// section 4.6.2.
			if numBodyBytes != ndpPrefixInformationLength {
				return nil, true, fmt.Errorf("got %d bytes for NDP Prefix Information option's body, expected %d bytes: %w", numBodyBytes, ndpPrefixInformationLength, ErrNDPOptMalformedBody)
			}

			return NDPPrefixInformation(body), false, nil

		case ndpRecursiveDNSServerOptionType:
			opt := NDPRecursiveDNSServer(body)
			if err := opt.checkAddresses(); err != nil {
				return nil, true, err
			}

			return opt, false, nil

		case ndpDNSSearchListOptionType:
			opt := NDPDNSSearchList(body)
			if err := opt.checkDomainNames(); err != nil {
				return nil, true, err
			}

			return opt, false, nil

		default:
			// We do not yet recognize the option, just skip for
			// now. This is okay because RFC 4861 allows us to
			// skip/ignore any unrecognized options. However,
			// we MUST recognized all the options in RFC 4861.
			//
			// TODO(b/141487990): Handle all NDP options as defined
			//                    by RFC 4861.
		}
	}
}

// NDPOptions is a buffer of NDP options as defined by RFC 4861 section 4.6.
type NDPOptions []byte

// Iter returns an iterator of NDPOption.
//
// If check is true, Iter will do an integrity check on the options by iterating
// over it and returning an error if detected.
//
// See NDPOptionIterator for more information.
func (b NDPOptions) Iter(check bool) (NDPOptionIterator, error) {
	it := NDPOptionIterator{
		opts: bytes.NewBuffer(b),
	}

	if check {
		it2 := NDPOptionIterator{
			opts: bytes.NewBuffer(b),
		}

		for {
			if _, done, err := it2.Next(); err != nil || done {
				return it, err
			}
		}
	}

	return it, nil
}

// Serialize serializes the provided list of NDP options into b.
//
// Note, b must be of sufficient size to hold all the options in s. See
// NDPOptionsSerializer.Length for details on the getting the total size
// of a serialized NDPOptionsSerializer.
//
// Serialize may panic if b is not of sufficient size to hold all the options
// in s.
func (b NDPOptions) Serialize(s NDPOptionsSerializer) int {
	done := 0

	for _, o := range s {
		l := paddedLength(o)

		if l == 0 {
			continue
		}

		b[0] = byte(o.kind())

		// We know this safe because paddedLength would have returned
		// 0 if o had an invalid length (> 255 * lengthByteUnits).
		b[1] = uint8(l / lengthByteUnits)

		// Serialize NDP option body.
		used := o.serializeInto(b[2:])

		// Zero out remaining (padding) bytes, if any exists.
		for i := used + 2; i < l; i++ {
			b[i] = 0
		}

		b = b[l:]
		done += l
	}

	return done
}

// NDPOption is the set of functions to be implemented by all NDP option types.
type NDPOption interface {
	fmt.Stringer

	// kind returns the type of the receiver.
	kind() ndpOptionIdentifier

	// length returns the length of the body of the receiver, in bytes.
	length() int

	// serializeInto serializes the receiver into the provided byte
	// buffer.
	//
	// Note, the caller MUST provide a byte buffer with size of at least
	// Length. Implementers of this function may assume that the byte buffer
	// is of sufficient size. serializeInto MAY panic if the provided byte
	// buffer is not of sufficient size.
	//
	// serializeInto will return the number of bytes that was used to
	// serialize the receiver. Implementers must only use the number of
	// bytes required to serialize the receiver. Callers MAY provide a
	// larger buffer than required to serialize into.
	serializeInto([]byte) int
}

// paddedLength returns the length of o, in bytes, with any padding bytes, if
// required.
func paddedLength(o NDPOption) int {
	l := o.length()

	if l == 0 {
		return 0
	}

	// Length excludes the 2 Type and Length bytes.
	l += 2

	// Add extra bytes if needed to make sure the option is
	// lengthByteUnits-byte aligned. We do this by adding lengthByteUnits-1
	// to l and then stripping off the last few LSBits from l. This will
	// make sure that l is rounded up to the nearest unit of
	// lengthByteUnits. This works since lengthByteUnits is a power of 2
	// (= 8).
	mask := lengthByteUnits - 1
	l += mask
	l &^= mask

	if l/lengthByteUnits > 255 {
		// Should never happen because an option can only have a max
		// value of 255 for its Length field, so just return 0 so this
		// option does not get serialized.
		//
		// Returning 0 here will make sure that this option does not get
		// serialized when NDPOptions.Serialize is called with the
		// NDPOptionsSerializer that holds this option, effectively
		// skipping this option during serialization. Also note that
		// a value of zero for the Length field in an NDP option is
		// invalid so this is another sign to the caller that this NDP
		// option is malformed, as per RFC 4861 section 4.6.
		return 0
	}

	return l
}

// NDPOptionsSerializer is a serializer for NDP options.
type NDPOptionsSerializer []NDPOption

// Length returns the total number of bytes required to serialize.
func (b NDPOptionsSerializer) Length() int {
	l := 0

	for _, o := range b {
		l += paddedLength(o)
	}

	return l
}

// NDPNonceOption is the NDP Nonce Option as defined by RFC 3971 section 5.3.2.
//
// It is the first X bytes following the NDP option's Type and Length field
// where X is the value in Length multiplied by lengthByteUnits - 2 bytes.
type NDPNonceOption []byte

// kind implements NDPOption.
func (o NDPNonceOption) kind() ndpOptionIdentifier {
	return ndpNonceOptionType
}

// length implements NDPOption.
func (o NDPNonceOption) length() int {
	return len(o)
}

// serializeInto implements NDPOption.
func (o NDPNonceOption) serializeInto(b []byte) int {
	return copy(b, o)
}

// String implements fmt.Stringer.
func (o NDPNonceOption) String() string {
	return fmt.Sprintf("%T(%x)", o, []byte(o))
}

// Nonce returns the nonce value this option holds.
func (o NDPNonceOption) Nonce() []byte {
	return []byte(o)
}

// NDPSourceLinkLayerAddressOption is the NDP Source Link Layer Option
// as defined by RFC 4861 section 4.6.1.
//
// It is the first X bytes following the NDP option's Type and Length field
// where X is the value in Length multiplied by lengthByteUnits - 2 bytes.
type NDPSourceLinkLayerAddressOption tcpip.LinkAddress

// kind implements NDPOption.
func (o NDPSourceLinkLayerAddressOption) kind() ndpOptionIdentifier {
	return ndpSourceLinkLayerAddressOptionType
}

// length implements NDPOption.
func (o NDPSourceLinkLayerAddressOption) length() int {
	return len(o)
}

// serializeInto implements NDPOption.
func (o NDPSourceLinkLayerAddressOption) serializeInto(b []byte) int {
	return copy(b, o)
}

// String implements fmt.Stringer.
func (o NDPSourceLinkLayerAddressOption) String() string {
	return fmt.Sprintf("%T(%s)", o, tcpip.LinkAddress(o))
}

// EthernetAddress will return an ethernet (MAC) address if the
// NDPSourceLinkLayerAddressOption's body has at minimum EthernetAddressSize
// bytes. If the body has more than EthernetAddressSize bytes, only the first
// EthernetAddressSize bytes are returned as that is all that is needed for an
// Ethernet address.
func (o NDPSourceLinkLayerAddressOption) EthernetAddress() tcpip.LinkAddress {
	if len(o) >= EthernetAddressSize {
		return tcpip.LinkAddress(o[:EthernetAddressSize])
	}

	return tcpip.LinkAddress([]byte(nil))
}

// NDPTargetLinkLayerAddressOption is the NDP Target Link Layer Option
// as defined by RFC 4861 section 4.6.1.
//
// It is the first X bytes following the NDP option's Type and Length field
// where X is the value in Length multiplied by lengthByteUnits - 2 bytes.
type NDPTargetLinkLayerAddressOption tcpip.LinkAddress

// kind implements NDPOption.
func (o NDPTargetLinkLayerAddressOption) kind() ndpOptionIdentifier {
	return ndpTargetLinkLayerAddressOptionType
}

// length implements NDPOption.
func (o NDPTargetLinkLayerAddressOption) length() int {
	return len(o)
}

// serializeInto implements NDPOption.
func (o NDPTargetLinkLayerAddressOption) serializeInto(b []byte) int {
	return copy(b, o)
}

// String implements fmt.Stringer.
func (o NDPTargetLinkLayerAddressOption) String() string {
	return fmt.Sprintf("%T(%s)", o, tcpip.LinkAddress(o))
}

// EthernetAddress will return an ethernet (MAC) address if the
// NDPTargetLinkLayerAddressOption's body has at minimum EthernetAddressSize
// bytes. If the body has more than EthernetAddressSize bytes, only the first
// EthernetAddressSize bytes are returned as that is all that is needed for an
// Ethernet address.
func (o NDPTargetLinkLayerAddressOption) EthernetAddress() tcpip.LinkAddress {
	if len(o) >= EthernetAddressSize {
		return tcpip.LinkAddress(o[:EthernetAddressSize])
	}

	return tcpip.LinkAddress([]byte(nil))
}

// NDPPrefixInformation is the NDP Prefix Information option as defined by
// RFC 4861 section 4.6.2.
//
// The length, in bytes, of a valid NDP Prefix Information option body MUST be
// ndpPrefixInformationLength bytes.
type NDPPrefixInformation []byte

// kind implements NDPOption.
func (o NDPPrefixInformation) kind() ndpOptionIdentifier {
	return ndpPrefixInformationType
}

// length implements NDPOption.
func (o NDPPrefixInformation) length() int {
	return ndpPrefixInformationLength
}

// serializeInto implements NDPOption.
func (o NDPPrefixInformation) serializeInto(b []byte) int {
	used := copy(b, o)

	// Zero out the Reserved1 field.
	b[ndpPrefixInformationFlagsOffset] &^= ndpPrefixInformationReserved1FlagsMask

	// Zero out the Reserved2 field.
	reserved2 := b[ndpPrefixInformationReserved2Offset:][:ndpPrefixInformationReserved2Length]
	for i := range reserved2 {
		reserved2[i] = 0
	}

	return used
}

// String implements fmt.Stringer.
func (o NDPPrefixInformation) String() string {
	return fmt.Sprintf("%T(O=%t, A=%t, PL=%s, VL=%s, Prefix=%s)",
		o,
		o.OnLinkFlag(),
		o.AutonomousAddressConfigurationFlag(),
		o.PreferredLifetime(),
		o.ValidLifetime(),
		o.Subnet())
}

// PrefixLength returns the value in the number of leading bits in the Prefix
// that are valid.
//
// Valid values are in the range [0, 128], but o may not always contain valid
// values. It is up to the caller to valdiate the Prefix Information option.
func (o NDPPrefixInformation) PrefixLength() uint8 {
	return o[ndpPrefixInformationPrefixLengthOffset]
}

// OnLinkFlag returns true of the prefix is considered on-link. On-link means
// that a forwarding node is not needed to send packets to other nodes on the
// same prefix.
//
// Note, when this function returns false, no statement is made about the
// on-link property of a prefix. That is, if OnLinkFlag returns false, the
// caller MUST NOT conclude that the prefix is off-link and MUST NOT update any
// previously stored state for this prefix about its on-link status.
func (o NDPPrefixInformation) OnLinkFlag() bool {
	return o[ndpPrefixInformationFlagsOffset]&ndpPrefixInformationOnLinkFlagMask != 0
}

// AutonomousAddressConfigurationFlag returns true if the prefix can be used for
// Stateless Address Auto-Configuration (as specified in RFC 4862).
func (o NDPPrefixInformation) AutonomousAddressConfigurationFlag() bool {
	return o[ndpPrefixInformationFlagsOffset]&ndpPrefixInformationAutoAddrConfFlagMask != 0
}

// ValidLifetime returns the length of time that the prefix is valid for the
// purpose of on-link determination. This value is relative to the send time of
// the packet that the Prefix Information option was present in.
//
// Note, a value of 0 implies the prefix should not be considered as on-link,
// and a value of infinity/forever is represented by
// NDPInfiniteLifetime.
func (o NDPPrefixInformation) ValidLifetime() time.Duration {
	// The field is the time in seconds, as per RFC 4861 section 4.6.2.
	return time.Second * time.Duration(binary.BigEndian.Uint32(o[ndpPrefixInformationValidLifetimeOffset:]))
}

// PreferredLifetime returns the length of time that an address generated from
// the prefix via Stateless Address Auto-Configuration remains preferred. This
// value is relative to the send time of the packet that the Prefix Information
// option was present in.
//
// Note, a value of 0 implies that addresses generated from the prefix should
// no longer remain preferred, and a value of infinity is represented by
// NDPInfiniteLifetime.
//
// Also note that the value of this field MUST NOT exceed the Valid Lifetime
// field to avoid preferring addresses that are no longer valid, for the
// purpose of Stateless Address Auto-Configuration.
func (o NDPPrefixInformation) PreferredLifetime() time.Duration {
	// The field is the time in seconds, as per RFC 4861 section 4.6.2.
	return time.Second * time.Duration(binary.BigEndian.Uint32(o[ndpPrefixInformationPreferredLifetimeOffset:]))
}

// Prefix returns an IPv6 address or a prefix of an IPv6 address. The Prefix
// Length field (see NDPPrefixInformation.PrefixLength) contains the number
// of valid leading bits in the prefix.
//
// Hosts SHOULD ignore an NDP Prefix Information option where the Prefix field
// holds the link-local prefix (fe80::).
func (o NDPPrefixInformation) Prefix() tcpip.Address {
	return tcpip.Address(o[ndpPrefixInformationPrefixOffset:][:IPv6AddressSize])
}

// Subnet returns the Prefix field and Prefix Length field represented in a
// tcpip.Subnet.
func (o NDPPrefixInformation) Subnet() tcpip.Subnet {
	addrWithPrefix := tcpip.AddressWithPrefix{
		Address:   o.Prefix(),
		PrefixLen: int(o.PrefixLength()),
	}
	return addrWithPrefix.Subnet()
}

// NDPRecursiveDNSServer is the NDP Recursive DNS Server option, as defined by
// RFC 8106 section 5.1.
//
// To make sure that the option meets its minimum length and does not end in the
// middle of a DNS server's IPv6 address, the length of a valid
// NDPRecursiveDNSServer must meet the following constraint:
//   (Length - ndpRecursiveDNSServerAddressesOffset) % IPv6AddressSize == 0
type NDPRecursiveDNSServer []byte

// Type returns the type of an NDP Recursive DNS Server option.
//
// kind implements NDPOption.
func (NDPRecursiveDNSServer) kind() ndpOptionIdentifier {
	return ndpRecursiveDNSServerOptionType
}

// length implements NDPOption.
func (o NDPRecursiveDNSServer) length() int {
	return len(o)
}

// serializeInto implements NDPOption.
func (o NDPRecursiveDNSServer) serializeInto(b []byte) int {
	used := copy(b, o)

	// Zero out the reserved bytes that are before the Lifetime field.
	for i := 0; i < ndpRecursiveDNSServerLifetimeOffset; i++ {
		b[i] = 0
	}

	return used
}

// String implements fmt.Stringer.
func (o NDPRecursiveDNSServer) String() string {
	lt := o.Lifetime()
	addrs, err := o.Addresses()
	if err != nil {
		return fmt.Sprintf("%T([] valid for %s; err = %s)", o, lt, err)
	}
	return fmt.Sprintf("%T(%s valid for %s)", o, addrs, lt)
}

// Lifetime returns the length of time that the DNS server addresses
// in this option may be used for name resolution.
//
// Note, a value of 0 implies the addresses should no longer be used,
// and a value of infinity/forever is represented by NDPInfiniteLifetime.
//
// Lifetime may panic if o does not have enough bytes to hold the Lifetime
// field.
func (o NDPRecursiveDNSServer) Lifetime() time.Duration {
	// The field is the time in seconds, as per RFC 8106 section 5.1.
	return time.Second * time.Duration(binary.BigEndian.Uint32(o[ndpRecursiveDNSServerLifetimeOffset:]))
}

// Addresses returns the recursive DNS server IPv6 addresses that may be
// used for name resolution.
//
// Note, the addresses MAY be link-local addresses.
func (o NDPRecursiveDNSServer) Addresses() ([]tcpip.Address, error) {
	var addrs []tcpip.Address
	return addrs, o.iterAddresses(func(addr tcpip.Address) { addrs = append(addrs, addr) })
}

// checkAddresses iterates over the addresses in an NDP Recursive DNS Server
// option and returns any error it encounters.
func (o NDPRecursiveDNSServer) checkAddresses() error {
	return o.iterAddresses(nil)
}

// iterAddresses iterates over the addresses in an NDP Recursive DNS Server
// option and calls a function with each valid unicast IPv6 address.
//
// Note, the addresses MAY be link-local addresses.
func (o NDPRecursiveDNSServer) iterAddresses(fn func(tcpip.Address)) error {
	if l := len(o); l < minNDPRecursiveDNSServerBodySize {
		return fmt.Errorf("got %d bytes for NDP Recursive DNS Server option's body, expected at least %d bytes: %w", l, minNDPRecursiveDNSServerBodySize, io.ErrUnexpectedEOF)
	}

	o = o[ndpRecursiveDNSServerAddressesOffset:]
	l := len(o)
	if l%IPv6AddressSize != 0 {
		return fmt.Errorf("NDP Recursive DNS Server option's body ends in the middle of an IPv6 address (addresses body size = %d bytes): %w", l, ErrNDPOptMalformedBody)
	}

	for i := 0; len(o) != 0; i++ {
		addr := tcpip.Address(o[:IPv6AddressSize])
		if !IsV6UnicastAddress(addr) {
			return fmt.Errorf("%d-th address (%s) in NDP Recursive DNS Server option is not a valid unicast IPv6 address: %w", i, addr, ErrNDPOptMalformedBody)
		}

		if fn != nil {
			fn(addr)
		}

		o = o[IPv6AddressSize:]
	}

	return nil
}

// NDPDNSSearchList is the NDP DNS Search List option, as defined by
// RFC 8106 section 5.2.
type NDPDNSSearchList []byte

// kind implements NDPOption.
func (o NDPDNSSearchList) kind() ndpOptionIdentifier {
	return ndpDNSSearchListOptionType
}

// length implements NDPOption.
func (o NDPDNSSearchList) length() int {
	return len(o)
}

// serializeInto implements NDPOption.
func (o NDPDNSSearchList) serializeInto(b []byte) int {
	used := copy(b, o)

	// Zero out the reserved bytes that are before the Lifetime field.
	for i := 0; i < ndpDNSSearchListLifetimeOffset; i++ {
		b[i] = 0
	}

	return used
}

// String implements fmt.Stringer.
func (o NDPDNSSearchList) String() string {
	lt := o.Lifetime()
	domainNames, err := o.DomainNames()
	if err != nil {
		return fmt.Sprintf("%T([] valid for %s; err = %s)", o, lt, err)
	}
	return fmt.Sprintf("%T(%s valid for %s)", o, domainNames, lt)
}

// Lifetime returns the length of time that the DNS search list of domain names
// in this option may be used for name resolution.
//
// Note, a value of 0 implies the domain names should no longer be used,
// and a value of infinity/forever is represented by NDPInfiniteLifetime.
func (o NDPDNSSearchList) Lifetime() time.Duration {
	// The field is the time in seconds, as per RFC 8106 section 5.1.
	return time.Second * time.Duration(binary.BigEndian.Uint32(o[ndpDNSSearchListLifetimeOffset:]))
}

// DomainNames returns a DNS search list of domain names.
//
// DomainNames will parse the backing buffer as outlined by RFC 1035 section
// 3.1 and return a list of strings, with all domain names in lower case.
func (o NDPDNSSearchList) DomainNames() ([]string, error) {
	var domainNames []string
	return domainNames, o.iterDomainNames(func(domainName string) { domainNames = append(domainNames, domainName) })
}

// checkDomainNames iterates over the domain names in an NDP DNS Search List
// option and returns any error it encounters.
func (o NDPDNSSearchList) checkDomainNames() error {
	return o.iterDomainNames(nil)
}

// iterDomainNames iterates over the domain names in an NDP DNS Search List
// option and calls a function with each valid domain name.
func (o NDPDNSSearchList) iterDomainNames(fn func(string)) error {
	if l := len(o); l < minNDPDNSSearchListBodySize {
		return fmt.Errorf("got %d bytes for NDP DNS Search List  option's body, expected at least %d bytes: %w", l, minNDPDNSSearchListBodySize, io.ErrUnexpectedEOF)
	}

	var searchList bytes.Reader
	searchList.Reset(o[ndpDNSSearchListDomainNamesOffset:])

	var scratch [maxDomainNameLength]byte
	domainName := bytes.NewBuffer(scratch[:])

	// Parse the domain names, as per RFC 1035 section 3.1.
	for searchList.Len() != 0 {
		domainName.Reset()

		// Parse a label within a domain name, as per RFC 1035 section 3.1.
		for {
			// The first byte is the label length.
			labelLenByte, err := searchList.ReadByte()
			if err != nil {
				if err != io.EOF {
					// ReadByte should only ever return nil or io.EOF.
					panic(fmt.Sprintf("unexpected error when reading a label's length: %s", err))
				}

				// We use io.ErrUnexpectedEOF as exhausting the buffer is unexpected
				// once we start parsing a domain name; we expect the buffer to contain
				// enough bytes for the whole domain name.
				return fmt.Errorf("unexpected exhausted buffer while parsing a new label for a domain from NDP Search List option: %w", io.ErrUnexpectedEOF)
			}
			labelLen := int(labelLenByte)

			// A zero-length label implies the end of a domain name.
			if labelLen == 0 {
				// If the domain name is empty or we have no callback function, do
				// nothing further with the current domain name.
				if domainName.Len() == 0 || fn == nil {
					break
				}

				// Ignore the trailing period in the parsed domain name.
				domainName.Truncate(domainName.Len() - 1)
				fn(domainName.String())
				break
			}

			// The label's length must not exceed the maximum length for a label.
			if labelLen > maxDomainNameLabelLength {
				return fmt.Errorf("label length of %d bytes is greater than the max label length of %d bytes for an NDP Search List option: %w", labelLen, maxDomainNameLabelLength, ErrNDPOptMalformedBody)
			}

			// The label (and trailing period) must not make the domain name too long.
			if labelLen+1 > domainName.Cap()-domainName.Len() {
				return fmt.Errorf("label would make an NDP Search List option's domain name longer than the max domain name length of %d bytes: %w", maxDomainNameLength, ErrNDPOptMalformedBody)
			}

			// Copy the label and add a trailing period.
			for i := 0; i < labelLen; i++ {
				b, err := searchList.ReadByte()
				if err != nil {
					if err != io.EOF {
						panic(fmt.Sprintf("unexpected error when reading domain name's label: %s", err))
					}

					return fmt.Errorf("read %d out of %d bytes for a domain name's label from NDP Search List option: %w", i, labelLen, io.ErrUnexpectedEOF)
				}

				// As per RFC 1035 section 2.3.1:
				//  1) the label must only contain ASCII include letters, digits and
				//     hyphens
				//  2) the first character in a label must be a letter
				//  3) the last letter in a label must be a letter or digit

				if !isLetter(b) {
					if i == 0 {
						return fmt.Errorf("first character of a domain name's label in an NDP Search List option must be a letter, got character code = %d: %w", b, ErrNDPOptMalformedBody)
					}

					if b == '-' {
						if i == labelLen-1 {
							return fmt.Errorf("last character of a domain name's label in an NDP Search List option must not be a hyphen (-): %w", ErrNDPOptMalformedBody)
						}
					} else if !isDigit(b) {
						return fmt.Errorf("domain name's label in an NDP Search List option may only contain letters, digits and hyphens, got character code = %d: %w", b, ErrNDPOptMalformedBody)
					}
				}

				// If b is an upper case character, make it lower case.
				if isUpperLetter(b) {
					b = b - 'A' + 'a'
				}

				if err := domainName.WriteByte(b); err != nil {
					panic(fmt.Sprintf("unexpected error writing label to domain name buffer: %s", err))
				}
			}
			if err := domainName.WriteByte('.'); err != nil {
				panic(fmt.Sprintf("unexpected error writing trailing period to domain name buffer: %s", err))
			}
		}
	}

	return nil
}

func isLetter(b byte) bool {
	return b >= 'a' && b <= 'z' || isUpperLetter(b)
}

func isUpperLetter(b byte) bool {
	return b >= 'A' && b <= 'Z'
}

func isDigit(b byte) bool {
	return b >= '0' && b <= '9'
}
