summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv6/option_iaaddress.go2
-rw-r--r--dhcpv6/option_iaprefix.go80
-rw-r--r--dhcpv6/option_iaprefix_test.go29
-rw-r--r--dhcpv6/option_prefixdelegation_test.go7
4 files changed, 56 insertions, 62 deletions
diff --git a/dhcpv6/option_iaaddress.go b/dhcpv6/option_iaaddress.go
index 0500d83..6f430db 100644
--- a/dhcpv6/option_iaaddress.go
+++ b/dhcpv6/option_iaaddress.go
@@ -47,7 +47,7 @@ func (op *OptIAAddress) Length() int {
func (op *OptIAAddress) String() string {
return fmt.Sprintf("OptIAAddress{ipv6addr=%v, preferredlifetime=%v, validlifetime=%v, options=%v}",
- net.IP(op.IPv6Addr[:]), op.PreferredLifetime, op.ValidLifetime, op.Options)
+ op.IPv6Addr, op.PreferredLifetime, op.ValidLifetime, op.Options)
}
// ParseOptIAAddress builds an OptIAAddress structure from a sequence
diff --git a/dhcpv6/option_iaprefix.go b/dhcpv6/option_iaprefix.go
index 1f68789..8a39531 100644
--- a/dhcpv6/option_iaprefix.go
+++ b/dhcpv6/option_iaprefix.go
@@ -10,11 +10,11 @@ import (
)
type OptIAPrefix struct {
- preferredLifetime uint32
- validLifetime uint32
+ PreferredLifetime uint32
+ ValidLifetime uint32
prefixLength byte
- ipv6Prefix [16]byte
- options []byte
+ ipv6Prefix net.IP
+ Options []Option
}
func (op *OptIAPrefix) Code() OptionCode {
@@ -25,30 +25,16 @@ func (op *OptIAPrefix) ToBytes() []byte {
buf := make([]byte, 12)
binary.BigEndian.PutUint16(buf[0:2], uint16(OptionIAPrefix))
binary.BigEndian.PutUint16(buf[2:4], uint16(op.Length()))
- binary.BigEndian.PutUint32(buf[4:8], op.preferredLifetime)
- binary.BigEndian.PutUint32(buf[8:12], op.validLifetime)
+ binary.BigEndian.PutUint32(buf[4:8], op.PreferredLifetime)
+ binary.BigEndian.PutUint32(buf[8:12], op.ValidLifetime)
buf = append(buf, op.prefixLength)
- buf = append(buf, op.ipv6Prefix[:]...)
- buf = append(buf, op.options...)
+ buf = append(buf, op.ipv6Prefix...)
+ for _, opt := range op.Options {
+ buf = append(buf, opt.ToBytes()...)
+ }
return buf
}
-func (op *OptIAPrefix) PreferredLifetime() uint32 {
- return op.preferredLifetime
-}
-
-func (op *OptIAPrefix) SetPreferredLifetime(pl uint32) {
- op.preferredLifetime = pl
-}
-
-func (op *OptIAPrefix) ValidLifetime() uint32 {
- return op.validLifetime
-}
-
-func (op *OptIAPrefix) SetValidLifetime(vl uint32) {
- op.validLifetime = vl
-}
-
func (op *OptIAPrefix) PrefixLength() byte {
return op.prefixLength
}
@@ -57,42 +43,56 @@ func (op *OptIAPrefix) SetPrefixLength(pl byte) {
op.prefixLength = pl
}
-func (op *OptIAPrefix) IPv6Prefix() []byte {
- return op.ipv6Prefix[:]
+// IPv6Prefix returns the ipv6Prefix
+func (op *OptIAPrefix) IPv6Prefix() net.IP {
+ return op.ipv6Prefix
}
-func (op *OptIAPrefix) SetIPv6Prefix(p [16]byte) {
+// SetIPv6Prefix sets the ipv6Prefix
+func (op *OptIAPrefix) SetIPv6Prefix(p net.IP) {
op.ipv6Prefix = p
}
-func (op *OptIAPrefix) Options() []byte {
- return op.options
+// Length returns the option length
+func (op *OptIAPrefix) Length() int {
+ opLen := 25
+ for _, opt := range op.Options {
+ opLen += 4 + opt.Length()
+ }
+ return opLen
}
-func (op *OptIAPrefix) SetOptions(options []byte) {
- op.options = options
+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)
}
-func (op *OptIAPrefix) Length() int {
- return 25 + len(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 getOption(op.Options, code)
}
-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, net.IP(op.ipv6Prefix[:]), op.options)
+// DelOption will remove all the options that match a Option code.
+func (op *OptIAPrefix) DelOption(code OptionCode) {
+ op.Options = delOption(op.Options, code)
}
// build an OptIAPrefix structure from a sequence of bytes.
// The input data does not include option code and length bytes.
func ParseOptIAPrefix(data []byte) (*OptIAPrefix, error) {
+ var err error
opt := OptIAPrefix{}
if len(data) < 25 {
return nil, fmt.Errorf("Invalid IA for Prefix Delegation data length. Expected at least 25 bytes, got %v", len(data))
}
- opt.preferredLifetime = binary.BigEndian.Uint32(data[:4])
- opt.validLifetime = binary.BigEndian.Uint32(data[4:8])
+ opt.PreferredLifetime = binary.BigEndian.Uint32(data[:4])
+ opt.ValidLifetime = binary.BigEndian.Uint32(data[4:8])
opt.prefixLength = data[8]
- copy(opt.ipv6Prefix[:], data[9:25])
- copy(opt.options, data[25:])
+ opt.ipv6Prefix = net.IP(data[9:25])
+ opt.Options, err = OptionsFromBytes(data[25:])
+ if err != nil {
+ return nil, err
+ }
return &opt, nil
}
diff --git a/dhcpv6/option_iaprefix_test.go b/dhcpv6/option_iaprefix_test.go
index f7b5b6b..2c4dea4 100644
--- a/dhcpv6/option_iaprefix_test.go
+++ b/dhcpv6/option_iaprefix_test.go
@@ -14,15 +14,16 @@ func TestOptIAPrefix(t *testing.T) {
0xee, 0xff, 0x00, 0x11, // validLifetime
36, // prefixLength
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // ipv6Prefix
+ 0, 8, 0, 2, 0xaa, 0xbb, // options
}
opt, err := ParseOptIAPrefix(buf)
if err != nil {
t.Fatal(err)
}
- if pl := opt.PreferredLifetime(); pl != 0xaabbccdd {
+ if pl := opt.PreferredLifetime; pl != 0xaabbccdd {
t.Fatalf("Invalid Preferred Lifetime. Expected 0xaabbccdd, got %v", pl)
}
- if vl := opt.ValidLifetime(); vl != 0xeeff0011 {
+ if vl := opt.ValidLifetime; vl != 0xeeff0011 {
t.Fatalf("Invalid Valid Lifetime. Expected 0xeeff0011, got %v", vl)
}
if pr := opt.PrefixLength(); pr != 36 {
@@ -31,6 +32,9 @@ func TestOptIAPrefix(t *testing.T) {
if ip := opt.IPv6Prefix(); !bytes.Equal(ip, net.IPv6loopback) {
t.Fatalf("Invalid Prefix Length. Expected %v, got %v", net.IPv6loopback, ip)
}
+ if opt.Length() != len(buf) {
+ t.Fatalf("Invalid Option Length. Expected %v, got %v", len(buf), opt.Length())
+ }
}
func TestOptIAPrefixToBytes(t *testing.T) {
@@ -39,14 +43,17 @@ func TestOptIAPrefixToBytes(t *testing.T) {
0xee, 0xff, 0x00, 0x11, // validLifetime
36, // prefixLength
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ipv6Prefix
+ 0, 8, 0, 2, 0xaa, 0xbb, // options
}
expected := []byte{00, 26, 00, byte(len(buf))}
expected = append(expected, buf...)
opt := OptIAPrefix{
- preferredLifetime: 0xaabbccdd,
- validLifetime: 0xeeff0011,
+ PreferredLifetime: 0xaabbccdd,
+ ValidLifetime: 0xeeff0011,
prefixLength: 36,
+ ipv6Prefix: net.IPv6zero,
}
+ opt.Options = append(opt.Options, &OptElapsedTime{ElapsedTime: 0xaabb})
toBytes := opt.ToBytes()
if !bytes.Equal(toBytes, expected) {
t.Fatalf("Invalid ToBytes result. Expected %v, got %v", expected, toBytes)
@@ -65,20 +72,6 @@ func TestOptIAPrefixParseInvalidTooShort(t *testing.T) {
}
}
-func TestOptIAPrefixSetGetOptions(t *testing.T) {
- opt := OptIAPrefix{
- preferredLifetime: 0xaabbccdd,
- validLifetime: 0xeeff0011,
- }
- expected := []byte{
- 0, 8, 0, 2, 0xaa, 0xbb, // options
- }
-
- require.Equal(t, []byte(nil), opt.Options(), "Options() should be blank by default")
- opt.SetOptions(expected)
- require.Equal(t, expected, opt.Options(), "Options() did not contain the correct data")
-}
-
func TestOptIAPrefixString(t *testing.T) {
buf := []byte{
0xaa, 0xbb, 0xcc, 0xdd, // preferredLifetime
diff --git a/dhcpv6/option_prefixdelegation_test.go b/dhcpv6/option_prefixdelegation_test.go
index cb90e25..93044fe 100644
--- a/dhcpv6/option_prefixdelegation_test.go
+++ b/dhcpv6/option_prefixdelegation_test.go
@@ -1,6 +1,7 @@
package dhcpv6
import (
+ "net"
"testing"
"github.com/stretchr/testify/require"
@@ -106,10 +107,10 @@ func TestOptIAForPrefixDelegationDelOption(t *testing.T) {
func TestOptIAForPrefixDelegationToBytes(t *testing.T) {
oaddr := OptIAPrefix{}
- oaddr.SetPreferredLifetime(0xaabbccdd)
- oaddr.SetValidLifetime(0xeeff0011)
+ oaddr.PreferredLifetime = 0xaabbccdd
+ oaddr.ValidLifetime = 0xeeff0011
oaddr.SetPrefixLength(36)
- oaddr.SetIPv6Prefix([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
+ oaddr.SetIPv6Prefix(net.IPv6loopback)
opt := OptIAForPrefixDelegation{}
opt.IaId = [4]byte{1, 2, 3, 4}