summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChris Koch <chrisko@google.com>2023-02-19 11:32:54 -0800
committerChris K <c@chrisko.ch>2023-02-19 13:39:52 -0800
commit223c67f573a916a45313dd6c17013e2ea804ce2a (patch)
tree92ebb00d6ce98ff2d8f97174358ec5915a728950
parent93dbaf95ae931da311e1671fd0f470f2aa5f6980 (diff)
dhcpv6 DUID: re-add Equal function
Signed-off-by: Chris Koch <chrisko@google.com>
-rw-r--r--dhcpv6/duid.go38
-rw-r--r--dhcpv6/duid_test.go98
2 files changed, 136 insertions, 0 deletions
diff --git a/dhcpv6/duid.go b/dhcpv6/duid.go
index fcd785d..027c6b0 100644
--- a/dhcpv6/duid.go
+++ b/dhcpv6/duid.go
@@ -1,6 +1,7 @@
package dhcpv6
import (
+ "bytes"
"fmt"
"net"
@@ -15,6 +16,7 @@ type DUID interface {
ToBytes() []byte
FromBytes(p []byte) error
DUIDType() DUIDType
+ Equal(d DUID) bool
}
// DUIDLLT is a DUID based on link-layer address plus time (RFC 8415 Section 11.2).
@@ -53,6 +55,15 @@ func (d *DUIDLLT) FromBytes(p []byte) error {
return buf.FinError()
}
+// Equal returns true if e is a DUID-LLT with the same values as d.
+func (d *DUIDLLT) Equal(e DUID) bool {
+ ellt, ok := e.(*DUIDLLT)
+ if !ok {
+ return false
+ }
+ return d.HWType == ellt.HWType && d.Time == ellt.Time && bytes.Equal(d.LinkLayerAddr, ellt.LinkLayerAddr)
+}
+
// DUIDLL is a DUID based on link-layer (RFC 8415 Section 11.4).
type DUIDLL struct {
HWType iana.HWType
@@ -86,6 +97,15 @@ func (d *DUIDLL) FromBytes(p []byte) error {
return buf.FinError()
}
+// Equal returns true if e is a DUID-LL with the same values as d.
+func (d *DUIDLL) Equal(e DUID) bool {
+ ell, ok := e.(*DUIDLL)
+ if !ok {
+ return false
+ }
+ return d.HWType == ell.HWType && bytes.Equal(d.LinkLayerAddr, ell.LinkLayerAddr)
+}
+
// DUIDEN is a DUID based on enterprise number (RFC 8415 Section 11.3).
type DUIDEN struct {
EnterpriseNumber uint32
@@ -119,6 +139,15 @@ func (d *DUIDEN) FromBytes(p []byte) error {
return buf.FinError()
}
+// Equal returns true if e is a DUID-EN with the same values as d.
+func (d *DUIDEN) Equal(e DUID) bool {
+ en, ok := e.(*DUIDEN)
+ if !ok {
+ return false
+ }
+ return d.EnterpriseNumber == en.EnterpriseNumber && bytes.Equal(d.EnterpriseIdentifier, en.EnterpriseIdentifier)
+}
+
// DUIDUUID is a DUID based on UUID (RFC 8415 Section 11.5).
type DUIDUUID struct {
// Defined by RFC 6355.
@@ -191,6 +220,15 @@ func (d *DUIDOpaque) FromBytes(p []byte) error {
return nil
}
+// Equal returns true if e is an opaque DUID with the same values as d.
+func (d *DUIDOpaque) Equal(e DUID) bool {
+ eopaque, ok := e.(*DUIDOpaque)
+ if !ok {
+ return false
+ }
+ return d.Type == eopaque.Type && bytes.Equal(d.Data, eopaque.Data)
+}
+
// DUIDType is the DUID type as defined in RFC 3315.
type DUIDType uint16
diff --git a/dhcpv6/duid_test.go b/dhcpv6/duid_test.go
index d035474..7174dc5 100644
--- a/dhcpv6/duid_test.go
+++ b/dhcpv6/duid_test.go
@@ -136,3 +136,101 @@ func TestFromBytes(t *testing.T) {
})
}
}
+
+func TestEqual(t *testing.T) {
+ for _, tt := range []struct {
+ name string
+ a DUID
+ b DUID
+ want bool
+ }{
+ {
+ name: "DUID-LL-equal",
+ a: &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ b: &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ want: true,
+ },
+ {
+ name: "DUID-LL-not-equal",
+ a: &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ b: &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}},
+ want: false,
+ },
+ {
+ name: "DUID-LL-and-DUID-EN",
+ a: &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ b: &DUIDEN{EnterpriseNumber: 5, EnterpriseIdentifier: []byte("foo")},
+ want: false,
+ },
+ {
+ name: "DUID-EN-equal",
+ a: &DUIDEN{EnterpriseNumber: 5, EnterpriseIdentifier: []byte("foo")},
+ b: &DUIDEN{EnterpriseNumber: 5, EnterpriseIdentifier: []byte("foo")},
+ want: true,
+ },
+ {
+ name: "DUID-EN-not-equal",
+ a: &DUIDEN{EnterpriseNumber: 5, EnterpriseIdentifier: []byte("foo")},
+ b: &DUIDEN{EnterpriseNumber: 5, EnterpriseIdentifier: []byte("bar")},
+ want: false,
+ },
+ {
+ name: "DUID-LLT-equal",
+ a: &DUIDLLT{HWType: iana.HWTypeEthernet, Time: 10, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ b: &DUIDLLT{HWType: iana.HWTypeEthernet, Time: 10, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ want: true,
+ },
+ {
+ name: "DUID-LLT-not-equal",
+ a: &DUIDLLT{HWType: iana.HWTypeEthernet, Time: 10, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ b: &DUIDLLT{HWType: iana.HWTypeEthernet, Time: 10, LinkLayerAddr: net.HardwareAddr{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}},
+ want: false,
+ },
+ {
+ name: "DUID-LLT-and-DUID-UUID",
+ a: &DUIDLLT{HWType: iana.HWTypeEthernet, Time: 10, LinkLayerAddr: net.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}},
+ b: &DUIDUUID{UUID: [16]byte{0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}},
+ want: false,
+ },
+ {
+ name: "DUID-UUID-equal",
+ a: &DUIDUUID{UUID: [16]byte{0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}},
+ b: &DUIDUUID{UUID: [16]byte{0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}},
+ want: true,
+ },
+ {
+ name: "DUID-UUID-not-equal",
+ a: &DUIDUUID{UUID: [16]byte{0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}},
+ b: &DUIDUUID{UUID: [16]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
+ want: false,
+ },
+ {
+ name: "DUID-UUID-and-DUID-Opaque",
+ a: &DUIDOpaque{Type: 5, Data: []byte{0x1}},
+ b: &DUIDUUID{UUID: [16]byte{0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}},
+ want: false,
+ },
+ {
+ name: "DUID-Opaque-equal",
+ a: &DUIDOpaque{Type: 5, Data: []byte{0x1}},
+ b: &DUIDOpaque{Type: 5, Data: []byte{0x1}},
+ want: true,
+ },
+ {
+ name: "DUID-Opaque-not-equal",
+ a: &DUIDOpaque{Type: 5, Data: []byte{0x1}},
+ b: &DUIDOpaque{Type: 5, Data: []byte{0x2}},
+ want: false,
+ },
+ } {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := tt.a.Equal(tt.b); got != tt.want {
+ t.Errorf("%s.Equal(%s) = %v, want %v", tt.a, tt.b, got, tt.want)
+ }
+
+ if got := tt.b.Equal(tt.a); got != tt.want {
+ t.Errorf("%s.Equal(%s) = %v, want %v", tt.b, tt.a, got, tt.want)
+ }
+ })
+ }
+}