summaryrefslogtreecommitdiffhomepage
path: root/dhcpv6/option_iaprefix.go
diff options
context:
space:
mode:
authorChris Koch <chrisko@google.com>2019-12-28 05:55:41 -0800
committerChris K <c@chrisko.ch>2020-03-11 13:52:51 -0700
commiteed709df9494fb0c994e41d7b8360a2f1b137b6e (patch)
treeedccc9faea9f1a18b73167edf39932714f8e2096 /dhcpv6/option_iaprefix.go
parent4d26b5e0b42f27fa41d872b15a7d2bc867787975 (diff)
v6: introduce Prefix options
IAPD has PDOptions which allows IAPrefix and StatusCode. IAPrefix has PrefixOptions which allow StatusCode. Signed-off-by: Chris Koch <chrisko@google.com>
Diffstat (limited to 'dhcpv6/option_iaprefix.go')
-rw-r--r--dhcpv6/option_iaprefix.go86
1 files changed, 48 insertions, 38 deletions
diff --git a/dhcpv6/option_iaprefix.go b/dhcpv6/option_iaprefix.go
index bb907b2..750f0cd 100644
--- a/dhcpv6/option_iaprefix.go
+++ b/dhcpv6/option_iaprefix.go
@@ -8,6 +8,30 @@ import (
"github.com/u-root/u-root/pkg/uio"
)
+// PrefixOptions are the options valid for use with IAPrefix option field.
+//
+// RFC 3633 states that it's just the StatusCode option.
+//
+// RFC 8415 Appendix C does not list the Status Code option as valid, but it
+// does say that the previous text in RFC 8415 Section 21.22 supersedes that
+// table. Section 21.22 does mention the Status Code option.
+type PrefixOptions struct {
+ Options
+}
+
+// Status returns the status code associated with this option.
+func (po PrefixOptions) Status() *OptStatusCode {
+ opt := po.Options.GetOne(OptionStatusCode)
+ if opt == nil {
+ return nil
+ }
+ sc, ok := opt.(*OptStatusCode)
+ if !ok {
+ return nil
+ }
+ return sc
+}
+
// OptIAPrefix implements the IAPrefix option.
//
// This module defines the OptIAPrefix structure.
@@ -15,9 +39,8 @@ import (
type OptIAPrefix struct {
PreferredLifetime time.Duration
ValidLifetime time.Duration
- prefixLength byte
- ipv6Prefix net.IP
- Options Options
+ Prefix *net.IPNet
+ Options PrefixOptions
}
func (op *OptIAPrefix) Code() OptionCode {
@@ -33,44 +56,22 @@ func (op *OptIAPrefix) ToBytes() []byte {
t2 := Duration{op.ValidLifetime}
t2.Marshal(buf)
- buf.Write8(op.prefixLength)
- write16(buf, op.ipv6Prefix)
+ if op.Prefix != nil {
+ // Even if Mask is nil, Size will return 0 without panicking.
+ length, _ := op.Prefix.Mask.Size()
+ buf.Write8(uint8(length))
+ write16(buf, op.Prefix.IP)
+ } else {
+ buf.Write8(0)
+ write16(buf, nil)
+ }
buf.WriteBytes(op.Options.ToBytes())
return buf.Data()
}
-func (op *OptIAPrefix) PrefixLength() byte {
- return op.prefixLength
-}
-
-func (op *OptIAPrefix) SetPrefixLength(pl byte) {
- op.prefixLength = pl
-}
-
-// IPv6Prefix returns the ipv6Prefix
-func (op *OptIAPrefix) IPv6Prefix() net.IP {
- return op.ipv6Prefix
-}
-
-// SetIPv6Prefix sets the ipv6Prefix
-func (op *OptIAPrefix) SetIPv6Prefix(p net.IP) {
- op.ipv6Prefix = p
-}
-
func (op *OptIAPrefix) String() string {
- return fmt.Sprintf("OptIAPrefix{preferredlifetime=%v, validlifetime=%v, prefixlength=%v, ipv6prefix=%v, options=%v}",
- op.PreferredLifetime, op.ValidLifetime, op.PrefixLength(), op.IPv6Prefix(), op.Options)
-}
-
-// GetOneOption will get an option of the give type from the Options field, if
-// it is present. It will return `nil` otherwise
-func (op *OptIAPrefix) GetOneOption(code OptionCode) Option {
- return op.Options.GetOne(code)
-}
-
-// DelOption will remove all the options that match a Option code.
-func (op *OptIAPrefix) DelOption(code OptionCode) {
- op.Options.Del(code)
+ return fmt.Sprintf("IAPrefix: {PreferredLifetime=%v, ValidLifetime=%v, Prefix=%s, Options=%v}",
+ op.PreferredLifetime, op.ValidLifetime, op.Prefix, op.Options)
}
// ParseOptIAPrefix an OptIAPrefix structure from a sequence of bytes. The
@@ -85,8 +86,17 @@ func ParseOptIAPrefix(data []byte) (*OptIAPrefix, error) {
opt.PreferredLifetime = t1.Duration
opt.ValidLifetime = t2.Duration
- opt.prefixLength = buf.Read8()
- opt.ipv6Prefix = net.IP(buf.CopyN(net.IPv6len))
+ length := buf.Read8()
+ ip := net.IP(buf.CopyN(net.IPv6len))
+
+ if length == 0 {
+ opt.Prefix = nil
+ } else {
+ opt.Prefix = &net.IPNet{
+ Mask: net.CIDRMask(int(length), 128),
+ IP: ip,
+ }
+ }
if err := opt.Options.FromBytes(buf.ReadAll()); err != nil {
return nil, err
}