...

Source file src/github.com/mdlayher/arp/client_request_test.go

Documentation: github.com/mdlayher/arp

     1  package arp
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"io"
     7  	"net"
     8  	"net/netip"
     9  	"testing"
    10  )
    11  
    12  func ipv6loopback() netip.Addr {
    13  	l := net.IPv6loopback
    14  	a, ok := netip.AddrFromSlice(l)
    15  	if !ok {
    16  		panic("invalid loopback address")
    17  	}
    18  	return a
    19  }
    20  
    21  func TestClientRequestNoIPv4Address(t *testing.T) {
    22  	c := &Client{}
    23  
    24  	_, got := c.Resolve(netip.Addr{})
    25  	if want := errNoIPv4Addr; want != got {
    26  		t.Fatalf("unexpected error for no IPv4 address:\n- want: %v\n-  got: %v",
    27  			want, got)
    28  	}
    29  }
    30  
    31  func TestClientRequestInvalidSourceHardwareAddr(t *testing.T) {
    32  	c := &Client{
    33  		ifi: &net.Interface{},
    34  		ip:  netip.IPv4Unspecified(),
    35  	}
    36  
    37  	_, got := c.Resolve(netip.IPv4Unspecified())
    38  	if want := ErrInvalidHardwareAddr; want != got {
    39  		t.Fatalf("unexpected error for invalid source hardware address:\n- want: %v\n-  got: %v",
    40  			want, got)
    41  	}
    42  }
    43  
    44  func TestClientRequestIPv6Address(t *testing.T) {
    45  	c := &Client{
    46  		ifi: &net.Interface{
    47  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
    48  		},
    49  		ip: netip.IPv4Unspecified(),
    50  	}
    51  
    52  	_, got := c.Resolve(ipv6loopback())
    53  	if want := ErrInvalidIP; want != got {
    54  		t.Fatalf("unexpected error for IPv6 address:\n- want: %v\n-  got: %v",
    55  			want, got)
    56  	}
    57  }
    58  
    59  func TestClientRequestErrWriteTo(t *testing.T) {
    60  	errWriteTo := errors.New("test error")
    61  
    62  	c := &Client{
    63  		ifi: &net.Interface{
    64  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
    65  		},
    66  		ip: netip.IPv4Unspecified(),
    67  		p: &errWriteToPacketConn{
    68  			err: errWriteTo,
    69  		},
    70  	}
    71  
    72  	_, got := c.Resolve(netip.IPv4Unspecified())
    73  	if want := errWriteTo; want != got {
    74  		t.Fatalf("unexpected error during WriteTo:\n- want: %v\n-  got: %v",
    75  			want, got)
    76  	}
    77  }
    78  
    79  func TestClientRequestErrReadFrom(t *testing.T) {
    80  	errReadFrom := errors.New("test error")
    81  
    82  	c := &Client{
    83  		ifi: &net.Interface{
    84  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
    85  		},
    86  		ip: netip.IPv4Unspecified(),
    87  		p: &errReadFromPacketConn{
    88  			err: errReadFrom,
    89  		},
    90  	}
    91  
    92  	_, got := c.Resolve(netip.IPv4Unspecified())
    93  	if want := errReadFrom; want != got {
    94  		t.Fatalf("unexpected error during ReadFrom:\n- want: %v\n-  got: %v",
    95  			want, got)
    96  	}
    97  }
    98  
    99  func TestClientRequestEthernetFrameUnexpectedEOF(t *testing.T) {
   100  	c := &Client{
   101  		ifi: &net.Interface{
   102  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
   103  		},
   104  		ip: netip.IPv4Unspecified(),
   105  		p: &bufferReadFromPacketConn{
   106  			b: bytes.NewBuffer([]byte{0}),
   107  		},
   108  	}
   109  
   110  	_, got := c.Resolve(netip.IPv4Unspecified())
   111  	if want := io.ErrUnexpectedEOF; want != got {
   112  		t.Fatalf("unexpected error while reading ethernet frame:\n- want: %v\n-  got: %v",
   113  			want, got)
   114  	}
   115  }
   116  
   117  func TestClientRequestEthernetFrameWrongDestinationHardwareAddr(t *testing.T) {
   118  	c := &Client{
   119  		ifi: &net.Interface{
   120  			HardwareAddr: net.HardwareAddr{0xde, 0xad, 0xbe, 0xef, 0xde, 0xad},
   121  		},
   122  		ip: netip.IPv4Unspecified(),
   123  		p: &bufferReadFromPacketConn{
   124  			b: bytes.NewBuffer(append([]byte{
   125  				// Ethernet frame with wrong destination hardware address
   126  				0, 0, 0, 0, 0, 0, // Wrong destination
   127  				0, 0, 0, 0, 0, 0,
   128  				0x00, 0x00,
   129  			}, make([]byte, 46)...)),
   130  		},
   131  	}
   132  
   133  	_, got := c.Resolve(netip.IPv4Unspecified())
   134  	if want := io.EOF; want != got {
   135  		t.Fatalf("unexpected error while reading ethernet frame with wrong destination hardware address:\n- want: %v\n-  got: %v",
   136  			want, got)
   137  	}
   138  }
   139  
   140  func TestClientRequestEthernetFrameWrongEtherType(t *testing.T) {
   141  	c := &Client{
   142  		ifi: &net.Interface{
   143  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
   144  		},
   145  		ip: netip.IPv4Unspecified(),
   146  		p: &bufferReadFromPacketConn{
   147  			b: bytes.NewBuffer(append([]byte{
   148  				// Ethernet frame with non-ARP EtherType
   149  				0, 0, 0, 0, 0, 0,
   150  				0, 0, 0, 0, 0, 0,
   151  				0x00, 0x00, // Wrong EtherType
   152  			}, make([]byte, 46)...)),
   153  		},
   154  	}
   155  
   156  	_, got := c.Resolve(netip.IPv4Unspecified())
   157  	if want := io.EOF; want != got {
   158  		t.Fatalf("unexpected error while reading ethernet frame with wrong EtherType:\n- want: %v\n-  got: %v",
   159  			want, got)
   160  	}
   161  }
   162  
   163  func TestClientRequestARPPacketUnexpectedEOF(t *testing.T) {
   164  	c := &Client{
   165  		ifi: &net.Interface{
   166  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
   167  		},
   168  		ip: netip.IPv4Unspecified(),
   169  		p: &bufferReadFromPacketConn{
   170  			b: bytes.NewBuffer(append([]byte{
   171  				// Ethernet frame
   172  				0, 0, 0, 0, 0, 0,
   173  				0, 0, 0, 0, 0, 0,
   174  				0x08, 0x06,
   175  				// ARP packet with misleading hardware address length
   176  				0, 0,
   177  				0, 0,
   178  				255, 255, // Misleading hardware address length
   179  			}, make([]byte, 40)...)),
   180  		},
   181  	}
   182  
   183  	_, got := c.Resolve(netip.IPv4Unspecified())
   184  	if want := io.ErrUnexpectedEOF; want != got {
   185  		t.Fatalf("unexpected error while reading ARP packet:\n- want: %v\n-  got: %v",
   186  			want, got)
   187  	}
   188  }
   189  
   190  func TestClientRequestARPRequestInsteadOfResponse(t *testing.T) {
   191  	c := &Client{
   192  		ifi: &net.Interface{
   193  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
   194  		},
   195  		ip: netip.IPv4Unspecified(),
   196  		p: &bufferReadFromPacketConn{
   197  			b: bytes.NewBuffer(append([]byte{
   198  				// Ethernet frame
   199  				0, 0, 0, 0, 0, 0,
   200  				0, 0, 0, 0, 0, 0,
   201  				0x08, 0x06,
   202  				// ARP request, not response
   203  				0, 1,
   204  				0x08, 0x06,
   205  				6,
   206  				4,
   207  				0, 1, // Request, not Response
   208  				0, 0, 0, 0, 0, 0,
   209  				0, 0, 0, 0,
   210  				0, 0, 0, 0, 0, 0,
   211  				0, 0, 0, 0,
   212  			}, make([]byte, 46)...)),
   213  		},
   214  	}
   215  
   216  	_, got := c.Resolve(netip.IPv4Unspecified())
   217  	if want := io.EOF; want != got {
   218  		t.Fatalf("unexpected error while reading ARP response with wrong operation type:\n- want: %v\n-  got: %v",
   219  			want, got)
   220  	}
   221  }
   222  
   223  func TestClientRequestARPResponseWrongSenderIP(t *testing.T) {
   224  	c := &Client{
   225  		ifi: &net.Interface{
   226  			HardwareAddr: net.HardwareAddr{0, 0, 0, 0, 0, 0},
   227  		},
   228  		ip: netip.AddrFrom4([4]byte{192, 168, 1, 1}),
   229  		p: &bufferReadFromPacketConn{
   230  			b: bytes.NewBuffer(append([]byte{
   231  				// Ethernet frame
   232  				0, 0, 0, 0, 0, 0,
   233  				0, 0, 0, 0, 0, 0,
   234  				0x08, 0x06,
   235  				// ARP Packet not bound for this IP address
   236  				0, 1,
   237  				0x08, 0x06,
   238  				6,
   239  				4,
   240  				0, 2,
   241  				0, 0, 0, 0, 0, 0,
   242  				192, 168, 1, 10, // Wrong IP address
   243  				0, 0, 0, 0, 0, 0,
   244  				192, 168, 1, 1,
   245  			}, make([]byte, 46)...)),
   246  		},
   247  	}
   248  
   249  	_, got := c.Resolve(netip.IPv4Unspecified())
   250  	if want := io.EOF; want != got {
   251  		t.Fatalf("unexpected error while reading ARP response with wrong sender IP:\n- want: %v\n-  got: %v",
   252  			want, got)
   253  	}
   254  }
   255  
   256  func TestClientRequestOK(t *testing.T) {
   257  	c := &Client{
   258  		ifi: &net.Interface{
   259  			HardwareAddr: net.HardwareAddr{0xde, 0xad, 0xbe, 0xef, 0xde, 0xad},
   260  		},
   261  		ip: netip.AddrFrom4([4]byte{192, 168, 1, 1}),
   262  		p: &bufferReadFromPacketConn{
   263  			b: bytes.NewBuffer(append([]byte{
   264  				// Ethernet frame
   265  				0xde, 0xad, 0xbe, 0xef, 0xde, 0xad,
   266  				0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
   267  				0x08, 0x06,
   268  				// ARP Packet
   269  				0, 1,
   270  				0x08, 0x06,
   271  				6,
   272  				4,
   273  				0, 2,
   274  				0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
   275  				192, 168, 1, 10,
   276  				0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, // mac needn't match ours
   277  				192, 168, 1, 2, // ip needn't match ours
   278  			}, make([]byte, 40)...)),
   279  		},
   280  	}
   281  
   282  	wantHW := net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
   283  	gotHW, err := c.Resolve(netip.AddrFrom4([4]byte{192, 168, 1, 10}))
   284  	if err != nil {
   285  		t.Fatal(err)
   286  	}
   287  
   288  	if want, got := wantHW, gotHW; !bytes.Equal(want, got) {
   289  		t.Fatalf("unexpected hardware address for request:\n- want: %v\n-  got: %v",
   290  			want, got)
   291  	}
   292  }
   293  
   294  // bufferReadFromPacketConn is a net.PacketConn which copies bytes from its
   295  // embedded buffer into b when when its ReadFrom method is called.
   296  type bufferReadFromPacketConn struct {
   297  	b *bytes.Buffer
   298  
   299  	noopPacketConn
   300  }
   301  
   302  func (p *bufferReadFromPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
   303  	n, err := p.b.Read(b)
   304  	return n, nil, err
   305  }
   306  
   307  // errWriteToPacketConn is a net.PacketConn which always returns its embedded
   308  // error when its WriteTo method is called.
   309  type errWriteToPacketConn struct {
   310  	err error
   311  
   312  	noopPacketConn
   313  }
   314  
   315  func (p *errWriteToPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) { return 0, p.err }
   316  
   317  // errReadFromPacketConn is a net.PacketConn which always returns its embedded
   318  // error when its ReadFrom method is called.
   319  type errReadFromPacketConn struct {
   320  	err error
   321  
   322  	noopPacketConn
   323  }
   324  
   325  func (p *errReadFromPacketConn) ReadFrom(b []byte) (int, net.Addr, error) { return 0, nil, p.err }
   326  

View as plain text