mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add a type to represent the NDP Router Advertisement message.
This change is in preparation for NDP Router Discovery where the stack will need to handle NDP Router Advertisments. Tests: Test that given an NDP Router Advertisement buffer (body of an ICMPv6 packet, correct values are returned by the field getters). PiperOrigin-RevId: 276146817
This commit is contained in:
committed by
gVisor bot
parent
c356fe2ebb
commit
515e0558d4
@@ -19,6 +19,7 @@ go_library(
|
||||
"ndp_neighbor_advert.go",
|
||||
"ndp_neighbor_solicit.go",
|
||||
"ndp_options.go",
|
||||
"ndp_router_advert.go",
|
||||
"tcp.go",
|
||||
"udp.go",
|
||||
],
|
||||
|
||||
@@ -18,6 +18,8 @@ import "gvisor.dev/gvisor/pkg/tcpip"
|
||||
|
||||
// NDPNeighborAdvert is an NDP Neighbor Advertisement message. It will
|
||||
// only contain the body of an ICMPv6 packet.
|
||||
//
|
||||
// See RFC 4861 section 4.4 for more details.
|
||||
type NDPNeighborAdvert []byte
|
||||
|
||||
const (
|
||||
|
||||
@@ -18,6 +18,8 @@ import "gvisor.dev/gvisor/pkg/tcpip"
|
||||
|
||||
// NDPNeighborSolicit is an NDP Neighbor Solicitation message. It will only
|
||||
// contain the body of an ICMPv6 packet.
|
||||
//
|
||||
// See RFC 4861 section 4.3 for more details.
|
||||
type NDPNeighborSolicit []byte
|
||||
|
||||
const (
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// 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 (
|
||||
"encoding/binary"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NDPRouterAdvert is an NDP Router Advertisement message. It will only contain
|
||||
// the body of an ICMPv6 packet.
|
||||
//
|
||||
// See RFC 4861 section 4.2 for more details.
|
||||
type NDPRouterAdvert []byte
|
||||
|
||||
const (
|
||||
// NDPRAMinimumSize is the minimum size of a valid NDP Router
|
||||
// Advertisement message (body of an ICMPv6 packet).
|
||||
NDPRAMinimumSize = 12
|
||||
|
||||
// ndpRACurrHopLimitOffset is the byte of the Curr Hop Limit field
|
||||
// within an NDPRouterAdvert.
|
||||
ndpRACurrHopLimitOffset = 0
|
||||
|
||||
// ndpRAFlagsOffset is the byte with the NDP RA bit-fields/flags
|
||||
// within an NDPRouterAdvert.
|
||||
ndpRAFlagsOffset = 1
|
||||
|
||||
// ndpRAManagedAddrConfFlagMask is the mask of the Managed Address
|
||||
// Configuration flag within the bit-field/flags byte of an
|
||||
// NDPRouterAdvert.
|
||||
ndpRAManagedAddrConfFlagMask = (1 << 7)
|
||||
|
||||
// ndpRAOtherConfFlagMask is the mask of the Other Configuration flag
|
||||
// within the bit-field/flags byte of an NDPRouterAdvert.
|
||||
ndpRAOtherConfFlagMask = (1 << 6)
|
||||
|
||||
// ndpRARouterLifetimeOffset is the start of the 2-byte Router Lifetime
|
||||
// field within an NDPRouterAdvert.
|
||||
ndpRARouterLifetimeOffset = 2
|
||||
|
||||
// ndpRAReachableTimeOffset is the start of the 4-byte Reachable Time
|
||||
// field within an NDPRouterAdvert.
|
||||
ndpRAReachableTimeOffset = 4
|
||||
|
||||
// ndpRARetransTimerOffset is the start of the 4-byte Retrans Timer
|
||||
// field within an NDPRouterAdvert.
|
||||
ndpRARetransTimerOffset = 8
|
||||
|
||||
// ndpRAOptionsOffset is the start of the NDP options in an
|
||||
// NDPRouterAdvert.
|
||||
ndpRAOptionsOffset = 12
|
||||
)
|
||||
|
||||
// CurrHopLimit returns the value of the Curr Hop Limit field.
|
||||
func (b NDPRouterAdvert) CurrHopLimit() uint8 {
|
||||
return b[ndpRACurrHopLimitOffset]
|
||||
}
|
||||
|
||||
// ManagedAddrConfFlag returns the value of the Managed Address Configuration
|
||||
// flag.
|
||||
func (b NDPRouterAdvert) ManagedAddrConfFlag() bool {
|
||||
return b[ndpRAFlagsOffset]&ndpRAManagedAddrConfFlagMask != 0
|
||||
}
|
||||
|
||||
// OtherConfFlag returns the value of the Other Configuration flag.
|
||||
func (b NDPRouterAdvert) OtherConfFlag() bool {
|
||||
return b[ndpRAFlagsOffset]&ndpRAOtherConfFlagMask != 0
|
||||
}
|
||||
|
||||
// RouterLifetime returns the lifetime associated with the default router. A
|
||||
// value of 0 means the source of the Router Advertisement is not a default
|
||||
// router and SHOULD NOT appear on the default router list. Note, a value of 0
|
||||
// only means that the router should not be used as a default router, it does
|
||||
// not apply to other information contained in the Router Advertisement.
|
||||
func (b NDPRouterAdvert) RouterLifetime() time.Duration {
|
||||
// The field is the time in seconds, as per RFC 4861 section 4.2.
|
||||
return time.Second * time.Duration(binary.BigEndian.Uint16(b[ndpRARouterLifetimeOffset:]))
|
||||
}
|
||||
|
||||
// ReachableTime returns the time that a node assumes a neighbor is reachable
|
||||
// after having received a reachability confirmation. A value of 0 means
|
||||
// that it is unspecified by the source of the Router Advertisement message.
|
||||
func (b NDPRouterAdvert) ReachableTime() time.Duration {
|
||||
// The field is the time in milliseconds, as per RFC 4861 section 4.2.
|
||||
return time.Millisecond * time.Duration(binary.BigEndian.Uint32(b[ndpRAReachableTimeOffset:]))
|
||||
}
|
||||
|
||||
// RetransTimer returns the time between retransmitted Neighbor Solicitation
|
||||
// messages. A value of 0 means that it is unspecified by the source of the
|
||||
// Router Advertisement message.
|
||||
func (b NDPRouterAdvert) RetransTimer() time.Duration {
|
||||
// The field is the time in milliseconds, as per RFC 4861 section 4.2.
|
||||
return time.Millisecond * time.Duration(binary.BigEndian.Uint32(b[ndpRARetransTimerOffset:]))
|
||||
}
|
||||
|
||||
// Options returns an NDPOptions of the the options body.
|
||||
func (b NDPRouterAdvert) Options() NDPOptions {
|
||||
return NDPOptions(b[ndpRAOptionsOffset:])
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package header
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/tcpip"
|
||||
)
|
||||
@@ -117,6 +118,40 @@ func TestNDPNeighborAdvert(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user