// Copyright 2018 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 arp_test

import (
	"context"
	"fmt"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"gvisor.dev/gvisor/pkg/tcpip"
	"gvisor.dev/gvisor/pkg/tcpip/buffer"
	"gvisor.dev/gvisor/pkg/tcpip/header"
	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
	"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
	"gvisor.dev/gvisor/pkg/tcpip/network/arp"
	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
	"gvisor.dev/gvisor/pkg/tcpip/stack"
	"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
)

const (
	nicID = 1

	stackAddr     = tcpip.Address("\x0a\x00\x00\x01")
	stackLinkAddr = tcpip.LinkAddress("\x0a\x0a\x0b\x0b\x0c\x0c")

	remoteAddr     = tcpip.Address("\x0a\x00\x00\x02")
	remoteLinkAddr = tcpip.LinkAddress("\x01\x02\x03\x04\x05\x06")

	unknownAddr = tcpip.Address("\x0a\x00\x00\x03")

	defaultChannelSize = 1
	defaultMTU         = 65536

	// eventChanSize defines the size of event channels used by the neighbor
	// cache's event dispatcher. The size chosen here needs to be sufficient to
	// queue all the events received during tests before consumption.
	// If eventChanSize is too small, the tests may deadlock.
	eventChanSize = 32
)

type eventType uint8

const (
	entryAdded eventType = iota
	entryChanged
	entryRemoved
)

func (t eventType) String() string {
	switch t {
	case entryAdded:
		return "add"
	case entryChanged:
		return "change"
	case entryRemoved:
		return "remove"
	default:
		return fmt.Sprintf("unknown (%d)", t)
	}
}

type eventInfo struct {
	eventType eventType
	nicID     tcpip.NICID
	entry     stack.NeighborEntry
}

func (e eventInfo) String() string {
	return fmt.Sprintf("%s event for NIC #%d, %#v", e.eventType, e.nicID, e.entry)
}

// arpDispatcher implements NUDDispatcher to validate the dispatching of
// events upon certain NUD state machine events.
type arpDispatcher struct {
	// C is where events are queued
	C chan eventInfo
}

var _ stack.NUDDispatcher = (*arpDispatcher)(nil)

func (d *arpDispatcher) OnNeighborAdded(nicID tcpip.NICID, entry stack.NeighborEntry) {
	e := eventInfo{
		eventType: entryAdded,
		nicID:     nicID,
		entry:     entry,
	}
	d.C <- e
}

func (d *arpDispatcher) OnNeighborChanged(nicID tcpip.NICID, entry stack.NeighborEntry) {
	e := eventInfo{
		eventType: entryChanged,
		nicID:     nicID,
		entry:     entry,
	}
	d.C <- e
}

func (d *arpDispatcher) OnNeighborRemoved(nicID tcpip.NICID, entry stack.NeighborEntry) {
	e := eventInfo{
		eventType: entryRemoved,
		nicID:     nicID,
		entry:     entry,
	}
	d.C <- e
}

func (d *arpDispatcher) waitForEvent(ctx context.Context, want eventInfo) error {
	select {
	case got := <-d.C:
		if diff := cmp.Diff(want, got, cmp.AllowUnexported(got), cmpopts.IgnoreFields(stack.NeighborEntry{}, "UpdatedAtNanos")); diff != "" {
			return fmt.Errorf("got invalid event (-want +got):\n%s", diff)
		}
	case <-ctx.Done():
		return fmt.Errorf("%s for %s", ctx.Err(), want)
	}
	return nil
}

func (d *arpDispatcher) waitForEventWithTimeout(want eventInfo, timeout time.Duration) error {
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	return d.waitForEvent(ctx, want)
}

func (d *arpDispatcher) nextEvent() (eventInfo, bool) {
	select {
	case event := <-d.C:
		return event, true
	default:
		return eventInfo{}, false
	}
}

type testContext struct {
	s       *stack.Stack
	linkEP  *channel.Endpoint
	nudDisp *arpDispatcher
}

func newTestContext(t *testing.T) *testContext {
	c := stack.DefaultNUDConfigurations()
	// Transition from Reachable to Stale almost immediately to test if receiving
	// probes refreshes positive reachability.
	c.BaseReachableTime = time.Microsecond

	d := arpDispatcher{
		// Create an event channel large enough so the neighbor cache doesn't block
		// while dispatching events. Blocking could interfere with the timing of
		// NUD transitions.
		C: make(chan eventInfo, eventChanSize),
	}

	s := stack.New(stack.Options{
		NetworkProtocols:   []stack.NetworkProtocolFactory{ipv4.NewProtocol, arp.NewProtocol},
		TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol4},
		NUDConfigs:         c,
		NUDDisp:            &d,
	})

	ep := channel.New(defaultChannelSize, defaultMTU, stackLinkAddr)
	ep.LinkEPCapabilities |= stack.CapabilityResolutionRequired

	wep := stack.LinkEndpoint(ep)

	if testing.Verbose() {
		wep = sniffer.New(ep)
	}
	if err := s.CreateNIC(nicID, wep); err != nil {
		t.Fatalf("CreateNIC failed: %v", err)
	}

	if err := s.AddAddress(nicID, ipv4.ProtocolNumber, stackAddr); err != nil {
		t.Fatalf("AddAddress for ipv4 failed: %v", err)
	}

	s.SetRouteTable([]tcpip.Route{{
		Destination: header.IPv4EmptySubnet,
		NIC:         nicID,
	}})

	return &testContext{
		s:       s,
		linkEP:  ep,
		nudDisp: &d,
	}
}

func (c *testContext) cleanup() {
	c.linkEP.Close()
}

func TestMalformedPacket(t *testing.T) {
	c := newTestContext(t)
	defer c.cleanup()

	v := make(buffer.View, header.ARPSize)
	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: v.ToVectorisedView(),
	})

	c.linkEP.InjectInbound(arp.ProtocolNumber, pkt)

	if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 {
		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
	}
	if got := c.s.Stats().ARP.MalformedPacketsReceived.Value(); got != 1 {
		t.Errorf("got c.s.Stats().ARP.MalformedPacketsReceived.Value() = %d, want = 1", got)
	}
}

func TestDisabledEndpoint(t *testing.T) {
	c := newTestContext(t)
	defer c.cleanup()

	ep, err := c.s.GetNetworkEndpoint(nicID, header.ARPProtocolNumber)
	if err != nil {
		t.Fatalf("GetNetworkEndpoint(%d, header.ARPProtocolNumber) failed: %s", nicID, err)
	}
	ep.Disable()

	v := make(buffer.View, header.ARPSize)
	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: v.ToVectorisedView(),
	})

	c.linkEP.InjectInbound(arp.ProtocolNumber, pkt)

	if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 {
		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
	}
	if got := c.s.Stats().ARP.DisabledPacketsReceived.Value(); got != 1 {
		t.Errorf("got c.s.Stats().ARP.DisabledPacketsReceived.Value() = %d, want = 1", got)
	}
}

func TestDirectReply(t *testing.T) {
	c := newTestContext(t)
	defer c.cleanup()

	const senderMAC = "\x01\x02\x03\x04\x05\x06"
	const senderIPv4 = "\x0a\x00\x00\x02"

	v := make(buffer.View, header.ARPSize)
	h := header.ARP(v)
	h.SetIPv4OverEthernet()
	h.SetOp(header.ARPReply)

	copy(h.HardwareAddressSender(), senderMAC)
	copy(h.ProtocolAddressSender(), senderIPv4)
	copy(h.HardwareAddressTarget(), stackLinkAddr)
	copy(h.ProtocolAddressTarget(), stackAddr)

	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
		Data: v.ToVectorisedView(),
	})

	c.linkEP.InjectInbound(arp.ProtocolNumber, pkt)

	if got := c.s.Stats().ARP.PacketsReceived.Value(); got != 1 {
		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
	}
	if got := c.s.Stats().ARP.RepliesReceived.Value(); got != 1 {
		t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = 1", got)
	}
}

func TestDirectRequest(t *testing.T) {
	c := newTestContext(t)
	defer c.cleanup()

	tests := []struct {
		name           string
		senderAddr     tcpip.Address
		senderLinkAddr tcpip.LinkAddress
		targetAddr     tcpip.Address
		isValid        bool
	}{
		{
			name:           "Loopback",
			senderAddr:     stackAddr,
			senderLinkAddr: stackLinkAddr,
			targetAddr:     stackAddr,
			isValid:        true,
		},
		{
			name:           "Remote",
			senderAddr:     remoteAddr,
			senderLinkAddr: remoteLinkAddr,
			targetAddr:     stackAddr,
			isValid:        true,
		},
		{
			name:           "RemoteInvalidTarget",
			senderAddr:     remoteAddr,
			senderLinkAddr: remoteLinkAddr,
			targetAddr:     unknownAddr,
			isValid:        false,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			packetsRecv := c.s.Stats().ARP.PacketsReceived.Value()
			requestsRecv := c.s.Stats().ARP.RequestsReceived.Value()
			requestsRecvUnknownAddr := c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value()
			outgoingReplies := c.s.Stats().ARP.OutgoingRepliesSent.Value()

			// Inject an incoming ARP request.
			v := make(buffer.View, header.ARPSize)
			h := header.ARP(v)
			h.SetIPv4OverEthernet()
			h.SetOp(header.ARPRequest)
			copy(h.HardwareAddressSender(), test.senderLinkAddr)
			copy(h.ProtocolAddressSender(), test.senderAddr)
			copy(h.ProtocolAddressTarget(), test.targetAddr)
			c.linkEP.InjectInbound(arp.ProtocolNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
				Data: v.ToVectorisedView(),
			}))

			if got, want := c.s.Stats().ARP.PacketsReceived.Value(), packetsRecv+1; got != want {
				t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = %d", got, want)
			}
			if got, want := c.s.Stats().ARP.RequestsReceived.Value(), requestsRecv+1; got != want {
				t.Errorf("got c.s.Stats().ARP.PacketsReceived.Value() = %d, want = %d", got, want)
			}

			if !test.isValid {
				// No packets should be sent after receiving an invalid ARP request.
				// There is no need to perform a blocking read here, since packets are
				// sent in the same function that handles ARP requests.
				if pkt, ok := c.linkEP.Read(); ok {
					t.Errorf("unexpected packet sent with network protocol number %d", pkt.Proto)
				}
				if got, want := c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value(), requestsRecvUnknownAddr+1; got != want {
					t.Errorf("got c.s.Stats().ARP.RequestsReceivedUnknownTargetAddress.Value() = %d, want = %d", got, want)
				}
				if got, want := c.s.Stats().ARP.OutgoingRepliesSent.Value(), outgoingReplies; got != want {
					t.Errorf("got c.s.Stats().ARP.OutgoingRepliesSent.Value() = %d, want = %d", got, want)
				}

				return
			}

			if got, want := c.s.Stats().ARP.OutgoingRepliesSent.Value(), outgoingReplies+1; got != want {
				t.Errorf("got c.s.Stats().ARP.OutgoingRepliesSent.Value() = %d, want = %d", got, want)
			}

			// Verify an ARP response was sent.
			pi, ok := c.linkEP.Read()
			if !ok {
				t.Fatal("expected ARP response to be sent, got none")
			}

			if pi.Proto != arp.ProtocolNumber {
				t.Fatalf("expected ARP response, got network protocol number %d", pi.Proto)
			}
			rep := header.ARP(pi.Pkt.NetworkHeader().View())
			if !rep.IsValid() {
				t.Fatalf("invalid ARP response: len = %d; response = %x", len(rep), rep)
			}
			if got, want := tcpip.LinkAddress(rep.HardwareAddressSender()), stackLinkAddr; got != want {
				t.Errorf("got HardwareAddressSender() = %s, want = %s", got, want)
			}
			if got, want := tcpip.Address(rep.ProtocolAddressSender()), tcpip.Address(h.ProtocolAddressTarget()); got != want {
				t.Errorf("got ProtocolAddressSender() = %s, want = %s", got, want)
			}
			if got, want := tcpip.LinkAddress(rep.HardwareAddressTarget()), tcpip.LinkAddress(h.HardwareAddressSender()); got != want {
				t.Errorf("got HardwareAddressTarget() = %s, want = %s", got, want)
			}
			if got, want := tcpip.Address(rep.ProtocolAddressTarget()), tcpip.Address(h.ProtocolAddressSender()); got != want {
				t.Errorf("got ProtocolAddressTarget() = %s, want = %s", got, want)
			}

			// Verify the sender was saved in the neighbor cache.
			wantEvent := eventInfo{
				eventType: entryAdded,
				nicID:     nicID,
				entry: stack.NeighborEntry{
					Addr:     test.senderAddr,
					LinkAddr: tcpip.LinkAddress(test.senderLinkAddr),
					State:    stack.Stale,
				},
			}
			if err := c.nudDisp.waitForEventWithTimeout(wantEvent, time.Second); err != nil {
				t.Fatal(err)
			}

			neighbors, err := c.s.Neighbors(nicID, ipv4.ProtocolNumber)
			if err != nil {
				t.Fatalf("c.s.Neighbors(%d, %d): %s", nicID, ipv4.ProtocolNumber, err)
			}

			neighborByAddr := make(map[tcpip.Address]stack.NeighborEntry)
			for _, n := range neighbors {
				if existing, ok := neighborByAddr[n.Addr]; ok {
					if diff := cmp.Diff(existing, n); diff != "" {
						t.Fatalf("duplicate neighbor entry found (-existing +got):\n%s", diff)
					}
					t.Fatalf("exact neighbor entry duplicate found for addr=%s", n.Addr)
				}
				neighborByAddr[n.Addr] = n
			}

			neigh, ok := neighborByAddr[test.senderAddr]
			if !ok {
				t.Fatalf("expected neighbor entry with Addr = %s", test.senderAddr)
			}
			if got, want := neigh.LinkAddr, test.senderLinkAddr; got != want {
				t.Errorf("got neighbor LinkAddr = %s, want = %s", got, want)
			}
			if got, want := neigh.State, stack.Stale; got != want {
				t.Errorf("got neighbor State = %s, want = %s", got, want)
			}

			// No more events should be dispatched
			for {
				event, ok := c.nudDisp.nextEvent()
				if !ok {
					break
				}
				t.Errorf("unexpected %s", event)
			}
		})
	}
}

var _ stack.LinkEndpoint = (*testLinkEndpoint)(nil)

type testLinkEndpoint struct {
	stack.LinkEndpoint

	writeErr tcpip.Error
}

func (t *testLinkEndpoint) WritePacket(r stack.RouteInfo, gso *stack.GSO, protocol tcpip.NetworkProtocolNumber, pkt *stack.PacketBuffer) tcpip.Error {
	if t.writeErr != nil {
		return t.writeErr
	}

	return t.LinkEndpoint.WritePacket(r, gso, protocol, pkt)
}

func TestLinkAddressRequest(t *testing.T) {
	const nicID = 1

	testAddr := tcpip.Address([]byte{1, 2, 3, 4})

	tests := []struct {
		name                                            string
		nicAddr                                         tcpip.Address
		localAddr                                       tcpip.Address
		remoteLinkAddr                                  tcpip.LinkAddress
		linkErr                                         tcpip.Error
		expectedErr                                     tcpip.Error
		expectedLocalAddr                               tcpip.Address
		expectedRemoteLinkAddr                          tcpip.LinkAddress
		expectedRequestsSent                            uint64
		expectedRequestBadLocalAddressErrors            uint64
		expectedRequestInterfaceHasNoLocalAddressErrors uint64
		expectedRequestDroppedErrors                    uint64
	}{
		{
			name:                                 "Unicast",
			nicAddr:                              stackAddr,
			localAddr:                            stackAddr,
			remoteLinkAddr:                       remoteLinkAddr,
			expectedLocalAddr:                    stackAddr,
			expectedRemoteLinkAddr:               remoteLinkAddr,
			expectedRequestsSent:                 1,
			expectedRequestBadLocalAddressErrors: 0,
			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Multicast",
			nicAddr:                              stackAddr,
			localAddr:                            stackAddr,
			remoteLinkAddr:                       "",
			expectedLocalAddr:                    stackAddr,
			expectedRemoteLinkAddr:               header.EthernetBroadcastAddress,
			expectedRequestsSent:                 1,
			expectedRequestBadLocalAddressErrors: 0,
			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Unicast with unspecified source",
			nicAddr:                              stackAddr,
			localAddr:                            "",
			remoteLinkAddr:                       remoteLinkAddr,
			expectedLocalAddr:                    stackAddr,
			expectedRemoteLinkAddr:               remoteLinkAddr,
			expectedRequestsSent:                 1,
			expectedRequestBadLocalAddressErrors: 0,
			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Multicast with unspecified source",
			nicAddr:                              stackAddr,
			localAddr:                            "",
			remoteLinkAddr:                       "",
			expectedLocalAddr:                    stackAddr,
			expectedRemoteLinkAddr:               header.EthernetBroadcastAddress,
			expectedRequestsSent:                 1,
			expectedRequestBadLocalAddressErrors: 0,
			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Unicast with unassigned address",
			nicAddr:                              stackAddr,
			localAddr:                            testAddr,
			remoteLinkAddr:                       remoteLinkAddr,
			expectedErr:                          &tcpip.ErrBadLocalAddress{},
			expectedRequestsSent:                 0,
			expectedRequestBadLocalAddressErrors: 1,
			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Multicast with unassigned address",
			nicAddr:                              stackAddr,
			localAddr:                            testAddr,
			remoteLinkAddr:                       "",
			expectedErr:                          &tcpip.ErrBadLocalAddress{},
			expectedRequestsSent:                 0,
			expectedRequestBadLocalAddressErrors: 1,
			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Unicast with no local address available",
			nicAddr:                              "",
			localAddr:                            "",
			remoteLinkAddr:                       remoteLinkAddr,
			expectedErr:                          &tcpip.ErrNetworkUnreachable{},
			expectedRequestsSent:                 0,
			expectedRequestBadLocalAddressErrors: 0,
			expectedRequestInterfaceHasNoLocalAddressErrors: 1,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Multicast with no local address available",
			nicAddr:                              "",
			localAddr:                            "",
			remoteLinkAddr:                       "",
			expectedErr:                          &tcpip.ErrNetworkUnreachable{},
			expectedRequestsSent:                 0,
			expectedRequestBadLocalAddressErrors: 0,
			expectedRequestInterfaceHasNoLocalAddressErrors: 1,
			expectedRequestDroppedErrors:                    0,
		},
		{
			name:                                 "Link error",
			nicAddr:                              stackAddr,
			localAddr:                            stackAddr,
			remoteLinkAddr:                       remoteLinkAddr,
			linkErr:                              &tcpip.ErrInvalidEndpointState{},
			expectedErr:                          &tcpip.ErrInvalidEndpointState{},
			expectedRequestsSent:                 0,
			expectedRequestBadLocalAddressErrors: 0,
			expectedRequestInterfaceHasNoLocalAddressErrors: 0,
			expectedRequestDroppedErrors:                    1,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			s := stack.New(stack.Options{
				NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocol, ipv4.NewProtocol},
			})
			linkEP := channel.New(defaultChannelSize, defaultMTU, stackLinkAddr)
			if err := s.CreateNIC(nicID, &testLinkEndpoint{LinkEndpoint: linkEP, writeErr: test.linkErr}); err != nil {
				t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
			}

			ep, err := s.GetNetworkEndpoint(nicID, arp.ProtocolNumber)
			if err != nil {
				t.Fatalf("s.GetNetworkEndpoint(%d, %d): %s", nicID, arp.ProtocolNumber, err)
			}
			linkRes, ok := ep.(stack.LinkAddressResolver)
			if !ok {
				t.Fatalf("expected %T to implement stack.LinkAddressResolver", ep)
			}

			if len(test.nicAddr) != 0 {
				if err := s.AddAddress(nicID, ipv4.ProtocolNumber, test.nicAddr); err != nil {
					t.Fatalf("s.AddAddress(%d, %d, %s): %s", nicID, ipv4.ProtocolNumber, test.nicAddr, err)
				}
			}

			{
				err := linkRes.LinkAddressRequest(remoteAddr, test.localAddr, test.remoteLinkAddr)
				if diff := cmp.Diff(test.expectedErr, err); diff != "" {
					t.Fatalf("unexpected error from p.LinkAddressRequest(%s, %s, %s, _), (-want, +got):\n%s", remoteAddr, test.localAddr, test.remoteLinkAddr, diff)
				}
			}

			if got := s.Stats().ARP.OutgoingRequestsSent.Value(); got != test.expectedRequestsSent {
				t.Errorf("got s.Stats().ARP.OutgoingRequestsSent.Value() = %d, want = %d", got, test.expectedRequestsSent)
			}
			if got := s.Stats().ARP.OutgoingRequestInterfaceHasNoLocalAddressErrors.Value(); got != test.expectedRequestInterfaceHasNoLocalAddressErrors {
				t.Errorf("got s.Stats().ARP.OutgoingRequestInterfaceHasNoLocalAddressErrors.Value() = %d, want = %d", got, test.expectedRequestInterfaceHasNoLocalAddressErrors)
			}
			if got := s.Stats().ARP.OutgoingRequestBadLocalAddressErrors.Value(); got != test.expectedRequestBadLocalAddressErrors {
				t.Errorf("got s.Stats().ARP.OutgoingRequestBadLocalAddressErrors.Value() = %d, want = %d", got, test.expectedRequestBadLocalAddressErrors)
			}
			if got := s.Stats().ARP.OutgoingRequestsDropped.Value(); got != test.expectedRequestDroppedErrors {
				t.Errorf("got s.Stats().ARP.OutgoingRequestsDropped.Value() = %d, want = %d", got, test.expectedRequestDroppedErrors)
			}

			if test.expectedErr != nil {
				return
			}

			pkt, ok := linkEP.Read()
			if !ok {
				t.Fatal("expected to send a link address request")
			}

			if pkt.Route.RemoteLinkAddress != test.expectedRemoteLinkAddr {
				t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, test.expectedRemoteLinkAddr)
			}

			rep := header.ARP(stack.PayloadSince(pkt.Pkt.NetworkHeader()))
			if got := rep.Op(); got != header.ARPRequest {
				t.Errorf("got Op = %d, want = %d", got, header.ARPRequest)
			}
			if got := tcpip.LinkAddress(rep.HardwareAddressSender()); got != stackLinkAddr {
				t.Errorf("got HardwareAddressSender = %s, want = %s", got, stackLinkAddr)
			}
			if got := tcpip.Address(rep.ProtocolAddressSender()); got != test.expectedLocalAddr {
				t.Errorf("got ProtocolAddressSender = %s, want = %s", got, test.expectedLocalAddr)
			}
			if got, want := tcpip.LinkAddress(rep.HardwareAddressTarget()), tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"); got != want {
				t.Errorf("got HardwareAddressTarget = %s, want = %s", got, want)
			}
			if got := tcpip.Address(rep.ProtocolAddressTarget()); got != remoteAddr {
				t.Errorf("got ProtocolAddressTarget = %s, want = %s", got, remoteAddr)
			}
		})
	}
}

func TestDADARPRequestPacket(t *testing.T) {
	s := stack.New(stack.Options{
		NetworkProtocols: []stack.NetworkProtocolFactory{arp.NewProtocolWithOptions(arp.Options{
			DADConfigs: stack.DADConfigurations{
				DupAddrDetectTransmits: 1,
				RetransmitTimer:        time.Second,
			},
		}), ipv4.NewProtocol},
	})
	e := channel.New(1, defaultMTU, stackLinkAddr)
	if err := s.CreateNIC(nicID, e); err != nil {
		t.Fatalf("s.CreateNIC(%d, _): %s", nicID, err)
	}

	if res, err := s.CheckDuplicateAddress(nicID, header.IPv4ProtocolNumber, remoteAddr, func(stack.DADResult) {}); err != nil {
		t.Fatalf("s.CheckDuplicateAddress(%d, %d, %s, _): %s", nicID, header.IPv4ProtocolNumber, remoteAddr, err)
	} else if res != stack.DADStarting {
		t.Fatalf("got s.CheckDuplicateAddress(%d, %d, %s, _) = %d, want = %d", nicID, header.IPv4ProtocolNumber, remoteAddr, res, stack.DADStarting)
	}

	pkt, ok := e.ReadContext(context.Background())
	if !ok {
		t.Fatal("expected to send an ARP request")
	}

	if pkt.Route.RemoteLinkAddress != header.EthernetBroadcastAddress {
		t.Errorf("got pkt.Route.RemoteLinkAddress = %s, want = %s", pkt.Route.RemoteLinkAddress, header.EthernetBroadcastAddress)
	}

	req := header.ARP(stack.PayloadSince(pkt.Pkt.NetworkHeader()))
	if !req.IsValid() {
		t.Errorf("got req.IsValid() = false, want = true")
	}
	if got := req.Op(); got != header.ARPRequest {
		t.Errorf("got req.Op() = %d, want = %d", got, header.ARPRequest)
	}
	if got := tcpip.LinkAddress(req.HardwareAddressSender()); got != stackLinkAddr {
		t.Errorf("got req.HardwareAddressSender() = %s, want = %s", got, stackLinkAddr)
	}
	if got := tcpip.Address(req.ProtocolAddressSender()); got != header.IPv4Any {
		t.Errorf("got req.ProtocolAddressSender() = %s, want = %s", got, header.IPv4Any)
	}
	if got, want := tcpip.LinkAddress(req.HardwareAddressTarget()), tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00"); got != want {
		t.Errorf("got req.HardwareAddressTarget() = %s, want = %s", got, want)
	}
	if got := tcpip.Address(req.ProtocolAddressTarget()); got != remoteAddr {
		t.Errorf("got req.ProtocolAddressTarget() = %s, want = %s", got, remoteAddr)
	}
}
