blob: 7297a61c1494bc6f11ef154aab399d4015c11cec [file] [log] [blame]
// 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"
"testing"
"time"
"github.com/google/netstack/tcpip"
)
// TestNDPNeighborSolicit tests the functions of NDPNeighborSolicit.
func TestNDPNeighborSolicit(t *testing.T) {
b := []byte{
0, 0, 0, 0,
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16,
}
// Test getting the Target Address.
ns := NDPNeighborSolicit(b)
addr := tcpip.Address("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10")
if got := ns.TargetAddress(); got != addr {
t.Fatalf("got ns.TargetAddress = %s, want %s", got, addr)
}
// Test updating the Target Address.
addr2 := tcpip.Address("\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x11")
ns.SetTargetAddress(addr2)
if got := ns.TargetAddress(); got != addr2 {
t.Fatalf("got ns.TargetAddress = %s, want %s", got, addr2)
}
// Make sure the address got updated in the backing buffer.
if got := tcpip.Address(b[ndpNSTargetAddessOffset:][:IPv6AddressSize]); got != addr2 {
t.Fatalf("got targetaddress buffer = %s, want %s", got, addr2)
}
}
// TestNDPNeighborAdvert tests the functions of NDPNeighborAdvert.
func TestNDPNeighborAdvert(t *testing.T) {
b := []byte{
160, 0, 0, 0,
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16,
}
// Test getting the Target Address.
na := NDPNeighborAdvert(b)
addr := tcpip.Address("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10")
if got := na.TargetAddress(); got != addr {
t.Fatalf("got TargetAddress = %s, want %s", got, addr)
}
// Test getting the Router Flag.
if got := na.RouterFlag(); !got {
t.Fatalf("got RouterFlag = false, want = true")
}
// Test getting the Solicited Flag.
if got := na.SolicitedFlag(); got {
t.Fatalf("got SolicitedFlag = true, want = false")
}
// Test getting the Override Flag.
if got := na.OverrideFlag(); !got {
t.Fatalf("got OverrideFlag = false, want = true")
}
// Test updating the Target Address.
addr2 := tcpip.Address("\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x11")
na.SetTargetAddress(addr2)
if got := na.TargetAddress(); got != addr2 {
t.Fatalf("got TargetAddress = %s, want %s", got, addr2)
}
// Make sure the address got updated in the backing buffer.
if got := tcpip.Address(b[ndpNATargetAddressOffset:][:IPv6AddressSize]); got != addr2 {
t.Fatalf("got targetaddress buffer = %s, want %s", got, addr2)
}
// Test updating the Router Flag.
na.SetRouterFlag(false)
if got := na.RouterFlag(); got {
t.Fatalf("got RouterFlag = true, want = false")
}
// Test updating the Solicited Flag.
na.SetSolicitedFlag(true)
if got := na.SolicitedFlag(); !got {
t.Fatalf("got SolicitedFlag = false, want = true")
}
// Test updating the Override Flag.
na.SetOverrideFlag(false)
if got := na.OverrideFlag(); got {
t.Fatalf("got OverrideFlag = true, want = false")
}
// Make sure flags got updated in the backing buffer.
if got := b[ndpNAFlagsOffset]; got != 64 {
t.Fatalf("got flags byte = %d, want = 64")
}
}
func TestNDPRouterAdvert(t *testing.T) {
b := []byte{
64, 128, 1, 2,
3, 4, 5, 6,
7, 8, 9, 10,
}
ra := NDPRouterAdvert(b)
if got := ra.CurrHopLimit(); got != 64 {
t.Fatalf("got ra.CurrHopLimit = %d, want = 64", got)
}
if got := ra.ManagedAddrConfFlag(); !got {
t.Fatalf("got ManagedAddrConfFlag = false, want = true")
}
if got := ra.OtherConfFlag(); got {
t.Fatalf("got OtherConfFlag = true, want = false")
}
if got, want := ra.RouterLifetime(), time.Second*258; got != want {
t.Fatalf("got ra.RouterLifetime = %d, want = %d", got, want)
}
if got, want := ra.ReachableTime(), time.Millisecond*50595078; got != want {
t.Fatalf("got ra.ReachableTime = %d, want = %d", got, want)
}
if got, want := ra.RetransTimer(), time.Millisecond*117967114; got != want {
t.Fatalf("got ra.RetransTimer = %d, want = %d", got, want)
}
}
// TestNDPTargetLinkLayerAddressOptionSerialize tests serializing a
// NDPTargetLinkLayerAddressOption.
func TestNDPTargetLinkLayerAddressOptionSerialize(t *testing.T) {
tests := []struct {
name string
buf []byte
expectedBuf []byte
addr tcpip.LinkAddress
}{
{
"Ethernet",
make([]byte, 8),
[]byte{2, 1, 1, 2, 3, 4, 5, 6},
"\x01\x02\x03\x04\x05\x06",
},
{
"Padding",
[]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
[]byte{2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0},
"\x01\x02\x03\x04\x05\x06\x07\x08",
},
{
"Empty",
[]byte{},
[]byte{},
"",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
opts := NDPOptions(test.buf)
serializer := NDPOptionsSerializer{
NDPTargetLinkLayerAddressOption(test.addr),
}
if got, want := int(serializer.Length()), len(test.expectedBuf); got != want {
t.Fatalf("got Length = %d, want = %d", got, want)
}
opts.Serialize(serializer)
if !bytes.Equal(test.buf, test.expectedBuf) {
t.Fatalf("got b = %d, want = %d", test.buf, test.expectedBuf)
}
})
}
}
// TestNDPPrefixInformationOption tests the field getters and serialization of a
// NDPPrefixInformation.
func TestNDPPrefixInformationOption(t *testing.T) {
b := []byte{
43, 127,
1, 2, 3, 4,
5, 6, 7, 8,
5, 5, 5, 5,
9, 10, 11, 12,
13, 14, 15, 16,
17, 18, 19, 20,
21, 22, 23, 24,
}
targetBuf := []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
opts := NDPOptions(targetBuf)
serializer := NDPOptionsSerializer{
NDPPrefixInformation(b),
}
opts.Serialize(serializer)
expectedBuf := []byte{
3, 4, 43, 64,
1, 2, 3, 4,
5, 6, 7, 8,
0, 0, 0, 0,
9, 10, 11, 12,
13, 14, 15, 16,
17, 18, 19, 20,
21, 22, 23, 24,
}
if !bytes.Equal(targetBuf, expectedBuf) {
t.Fatalf("got targetBuf = %x, want = %x", targetBuf, expectedBuf)
}
// First two bytes are the Type and Length fields, which are not part of
// the option body.
pi := NDPPrefixInformation(targetBuf[2:])
if got := pi.Type(); got != 3 {
t.Fatalf("got Type = %d, want = 3", got)
}
if got := pi.Length(); got != 30 {
t.Fatalf("got Length = %d, want = 30", got)
}
if got := pi.PrefixLength(); got != 43 {
t.Fatalf("got PrefixLength = %d, want = 43", got)
}
if pi.OnLinkFlag() {
t.Fatalf("got OnLinkFlag = true, want = false")
}
if !pi.AutonomousAddressConfigurationFlag() {
t.Fatalf("got AutonomousAddressConfigurationFlag = false, want = true")
}
if got, want := pi.ValidLifetime(), 16909060*time.Second; got != want {
t.Fatalf("got ValidLifetime = %d, want = %d", got, want)
}
if got, want := pi.PreferredLifetime(), 84281096*time.Second; got != want {
t.Fatalf("got PreferredLifetime = %d, want = %d", got, want)
}
if got, want := pi.Prefix(), tcpip.Address("\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18"); got != want {
t.Fatalf("got Prefix = %s, want = %s", got, want)
}
}