summaryrefslogtreecommitdiffhomepage
path: root/dhcpv6
diff options
context:
space:
mode:
authorTom McPhail <tom.mcphail@icloud.com>2020-08-11 22:51:23 +1000
committerTom McPhail <tom.mcphail@icloud.com>2020-08-13 21:10:11 +1000
commitf84fcf45711e9c41d21faa408dc85fe73439f3cd (patch)
tree6bf292909ab9f9c7ef8a7fc8d94ffba014f911ff /dhcpv6
parente10aec901335bf3bfea7ee5faf22cf0256f99420 (diff)
Added structure, parsing and convenience fuctions for OptInformationRefreshTime (32) https://tools.ietf.org/html/rfc8415#section-21.23
Signed-off-by: Tom McPhail <tom.mcphail@icloud.com>
Diffstat (limited to 'dhcpv6')
-rw-r--r--dhcpv6/dhcpv6message.go15
-rw-r--r--dhcpv6/modifiers.go7
-rw-r--r--dhcpv6/option_informationrefreshtime.go48
-rw-r--r--dhcpv6/option_informationrefreshtime_test.go33
-rw-r--r--dhcpv6/options.go2
5 files changed, 105 insertions, 0 deletions
diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go
index f3ed4ef..0dd219d 100644
--- a/dhcpv6/dhcpv6message.go
+++ b/dhcpv6/dhcpv6message.go
@@ -248,6 +248,21 @@ func (mo MessageOptions) ElapsedTime() time.Duration {
return 0
}
+// InformationRefreshTime returns the Information Refresh Time option
+// as defined by RFC 815 Section 21.23.
+//
+// InformationRefreshTime returns the provided default if no option is present.
+func (mo MessageOptions) InformationRefreshTime(def time.Duration) time.Duration {
+ opt := mo.Options.GetOne(OptionInformationRefreshTime)
+ if opt == nil {
+ return def
+ }
+ if t, ok := opt.(*optInformationRefreshTime); ok {
+ return t.InformationRefreshtime
+ }
+ return def
+}
+
// FQDN returns the FQDN option as defined by RFC 4704.
func (mo MessageOptions) FQDN() *OptFQDN {
opt := mo.Options.GetOne(OptionFQDN)
diff --git a/dhcpv6/modifiers.go b/dhcpv6/modifiers.go
index fbbad23..8c708d9 100644
--- a/dhcpv6/modifiers.go
+++ b/dhcpv6/modifiers.go
@@ -2,6 +2,7 @@ package dhcpv6
import (
"net"
+ "time"
"github.com/insomniacslk/dhcp/iana"
"github.com/insomniacslk/dhcp/rfc1035label"
@@ -175,3 +176,9 @@ func WithIAPD(iaid [4]byte, prefixes ...*OptIAPrefix) Modifier {
func WithClientLinkLayerAddress(ht iana.HWType, lla net.HardwareAddr) Modifier {
return WithOption(OptClientLinkLayerAddress(ht, lla))
}
+
+// WithInformationRefreshTime adds an optInformationRefreshTime to the DHCPv6 packet
+// using the provided duration
+func WithInformationRefreshTime(irt time.Duration) Modifier {
+ return WithOption(OptInformationRefreshTime(irt))
+}
diff --git a/dhcpv6/option_informationrefreshtime.go b/dhcpv6/option_informationrefreshtime.go
new file mode 100644
index 0000000..942d5c7
--- /dev/null
+++ b/dhcpv6/option_informationrefreshtime.go
@@ -0,0 +1,48 @@
+package dhcpv6
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/u-root/u-root/pkg/uio"
+)
+
+// OptInformationRefreshTime implements OptionInformationRefreshTime option.
+// https://tools.ietf.org/html/rfc8415#section-21.23
+func OptInformationRefreshTime(irt time.Duration) *optInformationRefreshTime {
+ return &optInformationRefreshTime{irt}
+}
+
+// optInformationRefreshTime represents an OptionInformationRefreshTime.
+type optInformationRefreshTime struct {
+ InformationRefreshtime time.Duration
+}
+
+// Code returns the option's code
+func (op *optInformationRefreshTime) Code() OptionCode {
+ return OptionInformationRefreshTime
+}
+
+// ToBytes serializes the option and returns it as a sequence of bytes
+func (op *optInformationRefreshTime) ToBytes() []byte {
+ buf := uio.NewBigEndianBuffer(nil)
+ irt := Duration{op.InformationRefreshtime}
+ irt.Marshal(buf)
+ return buf.Data()
+}
+
+func (op *optInformationRefreshTime) String() string {
+ return fmt.Sprintf("InformationRefreshTime: %v", op.InformationRefreshtime)
+}
+
+// parseOptInformationRefreshTime builds an optInformationRefreshTime structure from a sequence
+// of bytes. The input data does not include option code and length bytes.
+func parseOptInformationRefreshTime(data []byte) (*optInformationRefreshTime, error) {
+ var opt optInformationRefreshTime
+ buf := uio.NewBigEndianBuffer(data)
+
+ var irt Duration
+ irt.Unmarshal(buf)
+ opt.InformationRefreshtime = irt.Duration
+ return &opt, buf.FinError()
+}
diff --git a/dhcpv6/option_informationrefreshtime_test.go b/dhcpv6/option_informationrefreshtime_test.go
new file mode 100644
index 0000000..68f0855
--- /dev/null
+++ b/dhcpv6/option_informationrefreshtime_test.go
@@ -0,0 +1,33 @@
+package dhcpv6
+
+import (
+ "bytes"
+ "testing"
+ "time"
+)
+
+func TestOptInformationRefreshTime(t *testing.T) {
+ opt, err := parseOptInformationRefreshTime([]byte{0xaa, 0xbb, 0xcc, 0xdd})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if informationRefreshTime := opt.InformationRefreshtime; informationRefreshTime != time.Duration(0xaabbccdd) * time.Second {
+ t.Fatalf("Invalid information refresh time. Expected 0xaabb, got %v", informationRefreshTime)
+ }
+}
+
+func TestOptInformationRefreshTimeToBytes(t *testing.T) {
+ opt := OptInformationRefreshTime(0)
+ expected := []byte{0, 0, 0, 0}
+ if toBytes := opt.ToBytes(); !bytes.Equal(expected, toBytes) {
+ t.Fatalf("Invalid ToBytes output. Expected %v, got %v", expected, toBytes)
+ }
+}
+
+func TestOptInformationRefreshTimeString(t *testing.T) {
+ opt := OptInformationRefreshTime(3600 * time.Second)
+ expected := "InformationRefreshTime: 1h0m0s"
+ if optString := opt.String(); optString != expected {
+ t.Fatalf("Invalid elapsed time string. Expected %v, got %v", expected, optString)
+ }
+}
diff --git a/dhcpv6/options.go b/dhcpv6/options.go
index 16bc8d7..0ff5148 100644
--- a/dhcpv6/options.go
+++ b/dhcpv6/options.go
@@ -75,6 +75,8 @@ func ParseOption(code OptionCode, optData []byte) (Option, error) {
opt, err = ParseOptIAPD(optData)
case OptionIAPrefix:
opt, err = ParseOptIAPrefix(optData)
+ case OptionInformationRefreshTime:
+ opt, err = parseOptInformationRefreshTime(optData)
case OptionRemoteID:
opt, err = ParseOptRemoteID(optData)
case OptionFQDN: