diff options
author | Chris Koch <chrisko@google.com> | 2023-02-19 11:32:54 -0800 |
---|---|---|
committer | Chris K <c@chrisko.ch> | 2023-02-19 13:39:52 -0800 |
commit | 223c67f573a916a45313dd6c17013e2ea804ce2a (patch) | |
tree | 92ebb00d6ce98ff2d8f97174358ec5915a728950 | |
parent | 93dbaf95ae931da311e1671fd0f470f2aa5f6980 (diff) |
dhcpv6 DUID: re-add Equal function
Signed-off-by: Chris Koch <chrisko@google.com>
-rw-r--r-- | dhcpv6/duid.go | 38 | ||||
-rw-r--r-- | dhcpv6/duid_test.go | 98 |
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) + } + }) + } +} |