Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option IPv6OnlyPreferred (RFC 8925) #524

Merged
merged 1 commit into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions dhcpv4/dhcpv4.go
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,22 @@ func (d *DHCPv4) IPAddressRebindingTime(def time.Duration) time.Duration {
return time.Duration(dur)
}

// IPv6OnlyPreferred returns the V6ONLY_WAIT duration, and a boolean
// indicating whether this option was present.
//
// The IPv6-Only Preferred option is described by RFC 8925, Section 3.1.
func (d *DHCPv4) IPv6OnlyPreferred() (time.Duration, bool) {
pmazzini marked this conversation as resolved.
Show resolved Hide resolved
v := d.Options.Get(OptionIPv6OnlyPreferred)
if v == nil {
return 0, false
}
var dur Duration
if err := dur.FromBytes(v); err != nil {
return 0, false
}
return time.Duration(dur), true
}

// MaxMessageSize returns the DHCP Maximum Message Size if present.
//
// The Maximum DHCP Message Size option is described by RFC 2132, Section 9.10.
Expand Down
5 changes: 5 additions & 0 deletions dhcpv4/modifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ func WithLeaseTime(leaseTime uint32) Modifier {
return WithOption(OptIPAddressLeaseTime(time.Duration(leaseTime) * time.Second))
}

// WithIPv6OnlyPreferred adds or updates an OptIPv6OnlyPreferred
func WithIPv6OnlyPreferred(v6OnlyWait uint32) Modifier {
return WithOption(OptIPv6OnlyPreferred(time.Duration(v6OnlyWait) * time.Second))
}

// WithDomainSearchList adds or updates an OptionDomainSearch
func WithDomainSearchList(searchList ...string) Modifier {
return WithOption(OptDomainSearch(&rfc1035label.Labels{
Expand Down
9 changes: 9 additions & 0 deletions dhcpv4/modifiers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ func TestWithDNS(t *testing.T) {
require.Equal(t, net.ParseIP("10.0.0.2").To4(), dns[1])
}

func TestWithIPv6OnlyPreferred(t *testing.T) {
d, err := New(WithIPv6OnlyPreferred(300))
require.NoError(t, err)

v6pref, ok := d.IPv6OnlyPreferred()
require.True(t, ok)
require.Equal(t, 300*time.Second, v6pref)
}

func TestWithDomainSearchList(t *testing.T) {
d, err := New(WithDomainSearchList("slackware.it", "dhcp.slackware.it"))
require.NoError(t, err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ func (d Duration) String() string {
func OptIPAddressLeaseTime(d time.Duration) Option {
return Option{Code: OptionIPAddressLeaseTime, Value: Duration(d)}
}

// The IPv6-Only Preferred option is described by RFC 8925, Section 3.1
func OptIPv6OnlyPreferred(d time.Duration) Option {
return Option{Code: OptionIPv6OnlyPreferred, Value: Duration(d)}
}
71 changes: 71 additions & 0 deletions dhcpv4/option_duration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package dhcpv4

import (
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestOptIPAddressLeaseTime(t *testing.T) {
o := OptIPAddressLeaseTime(43200 * time.Second)
require.Equal(t, OptionIPAddressLeaseTime, o.Code, "Code")
require.Equal(t, []byte{0, 0, 168, 192}, o.Value.ToBytes(), "ToBytes")
require.Equal(t, "IP Addresses Lease Time: 12h0m0s", o.String(), "String")
}

func TestGetIPAddressLeaseTime(t *testing.T) {
m, _ := New(WithGeneric(OptionIPAddressLeaseTime, []byte{0, 0, 168, 192}))
leaseTime := m.IPAddressLeaseTime(0)
require.Equal(t, 43200*time.Second, leaseTime)

// Too short.
m, _ = New(WithGeneric(OptionIPAddressLeaseTime, []byte{168, 192}))
leaseTime = m.IPAddressLeaseTime(0)
require.Equal(t, time.Duration(0), leaseTime)

// Too long.
m, _ = New(WithGeneric(OptionIPAddressLeaseTime, []byte{1, 1, 1, 1, 1}))
leaseTime = m.IPAddressLeaseTime(0)
require.Equal(t, time.Duration(0), leaseTime)

// Empty.
m, _ = New()
require.Equal(t, time.Duration(10), m.IPAddressLeaseTime(10))
}

func TestOptIPv6OnlyPreferred(t *testing.T) {
o := OptIPv6OnlyPreferred(43200 * time.Second)
require.Equal(t, OptionIPv6OnlyPreferred, o.Code, "Code")
require.Equal(t, []byte{0, 0, 168, 192}, o.Value.ToBytes(), "ToBytes")
require.Equal(t, "IPv6-Only Preferred: 12h0m0s", o.String(), "String")
}

func TestOptIPv6OnlyPreferredZero(t *testing.T) {
o := OptIPv6OnlyPreferred(0)
require.Equal(t, OptionIPv6OnlyPreferred, o.Code, "Code")
require.Equal(t, []byte{0, 0, 0, 0}, o.Value.ToBytes(), "ToBytes")
require.Equal(t, "IPv6-Only Preferred: 0s", o.String(), "String")
}

func TestGetIPv6OnlyPreferred(t *testing.T) {
m, _ := New(WithGeneric(OptionIPv6OnlyPreferred, []byte{0, 0, 168, 192}))
v6onlyWait, ok := m.IPv6OnlyPreferred()
require.True(t, ok)
require.Equal(t, 43200*time.Second, v6onlyWait)

// Too short.
m, _ = New(WithGeneric(OptionIPv6OnlyPreferred, []byte{168, 192}))
_, ok = m.IPv6OnlyPreferred()
require.False(t, ok)

// Too long.
m, _ = New(WithGeneric(OptionIPv6OnlyPreferred, []byte{1, 1, 1, 1, 1}))
_, ok = m.IPv6OnlyPreferred()
require.False(t, ok)

// Missing.
m, _ = New()
_, ok = m.IPv6OnlyPreferred()
require.False(t, ok)
}
35 changes: 0 additions & 35 deletions dhcpv4/option_ip_address_lease_time_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion dhcpv4/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ func getOption(code OptionCode, data []byte, vendorDecoder OptionDecoder) fmt.St
case OptionDNSDomainSearchList:
d = &rfc1035label.Labels{}

case OptionIPAddressLeaseTime:
case OptionIPAddressLeaseTime, OptionIPv6OnlyPreferred:
var dur Duration
d = &dur

Expand Down
4 changes: 4 additions & 0 deletions dhcpv4/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ const (
OptionGeoConfCivic optionCode = 99
OptionIEEE10031TZString optionCode = 100
OptionReferenceToTZDatabase optionCode = 101
// Option 108 returned in RFC 8925
OptionIPv6OnlyPreferred optionCode = 108
// Options 102-111 returned in RFC 3679
OptionNetInfoParentServerAddress optionCode = 112
OptionNetInfoParentServerTag optionCode = 113
Expand Down Expand Up @@ -401,6 +403,8 @@ var optionCodeToString = map[OptionCode]string{
OptionGeoConfCivic: "GEOCONF_CIVIC",
OptionIEEE10031TZString: "IEEE 1003.1 TZ String",
OptionReferenceToTZDatabase: "Reference to the TZ Database",
// Option 108 returned in RFC 8925
OptionIPv6OnlyPreferred: "IPv6-Only Preferred",
// Options 102-111 returned in RFC 3679
OptionNetInfoParentServerAddress: "NetInfo Parent Server Address",
OptionNetInfoParentServerTag: "NetInfo Parent Server Tag",
Expand Down
Loading