Skip to content

Commit

Permalink
Add option IPv6OnlyPreferred (RFC 8925)
Browse files Browse the repository at this point in the history
Signed-off-by: Brian Candler <[email protected]>
  • Loading branch information
candlerb committed Feb 26, 2024
1 parent ca2dc33 commit ca1a9bd
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 1 deletion.
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 true if this option is present, and the
// V6ONLY_WAIT duration if it is.
//
// The IPv6-Only Preferred option is described by RFC 8195, Section 3.1.
func (d *DHCPv4) IPv6OnlyPreferred() (bool, time.Duration) {
v := d.Options.Get(OptionIPv6OnlyPreferred)
if v == nil {
return false, 0
}
var dur Duration
if err := dur.FromBytes(v); err != nil {
return false, 0
}
return true, time.Duration(dur)
}

// 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
10 changes: 10 additions & 0 deletions dhcpv4/option_ipv6_only_preferred.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dhcpv4

import (
"time"
)

// 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)}
}
43 changes: 43 additions & 0 deletions dhcpv4/option_ipv6_only_preferred_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package dhcpv4

import (
"testing"
"time"

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

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}))
found, v6onlyWait := m.IPv6OnlyPreferred()
require.True(t, found)
require.Equal(t, 43200*time.Second, v6onlyWait)

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

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

// Empty.
m, _ = New()
require.False(t, found)
}
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

0 comments on commit ca1a9bd

Please sign in to comment.