// 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 = 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.Type())

		// 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

	// Type returns the type of the receiver.
	Type() 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

// Type implements NDPOption.
func (o NDPNonceOption) Type() 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

// Type implements NDPOption.Type.
func (o NDPSourceLinkLayerAddressOption) Type() NDPOptionIdentifier {
	return NDPSourceLinkLayerAddressOptionType
}

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

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

// String implements fmt.Stringer.String.
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

// Type implements NDPOption.Type.
func (o NDPTargetLinkLayerAddressOption) Type() NDPOptionIdentifier {
	return NDPTargetLinkLayerAddressOptionType
}

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

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

// String implements fmt.Stringer.String.
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

// Type implements NDPOption.Type.
func (o NDPPrefixInformation) Type() NDPOptionIdentifier {
	return NDPPrefixInformationType
}

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

// serializeInto implements NDPOption.serializeInto.
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.String.
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.
//
// Type implements NDPOption.Type.
func (NDPRecursiveDNSServer) Type() NDPOptionIdentifier {
	return NDPRecursiveDNSServerOptionType
}

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

// serializeInto implements NDPOption.serializeInto.
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.String.
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

// Type implements NDPOption.Type.
func (o NDPDNSSearchList) Type() NDPOptionIdentifier {
	return NDPDNSSearchListOptionType
}

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

// serializeInto implements NDPOption.serializeInto.
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.String.
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'
}
