summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChris Koch <chrisko@google.com>2023-02-24 21:39:24 -0800
committerChris K <c@chrisko.ch>2023-02-27 10:35:19 -0800
commitc063ce388b0632ce267a0ff9af24e186504ebcaa (patch)
tree1786dfeb50daf44bac4943c58044a21df8301a73
parent64b8c3dee967713689d8b65259d888af2076f1d9 (diff)
New tests for ClientID & ServerID
Signed-off-by: Chris Koch <chrisko@google.com>
-rw-r--r--dhcpv6/duid.go17
-rw-r--r--dhcpv6/option_clientid_test.go160
-rw-r--r--dhcpv6/option_serverid_test.go164
-rw-r--r--dhcpv6/options.go4
-rw-r--r--go.mod3
-rw-r--r--go.sum5
6 files changed, 198 insertions, 155 deletions
diff --git a/dhcpv6/duid.go b/dhcpv6/duid.go
index 027c6b0..0470f9f 100644
--- a/dhcpv6/duid.go
+++ b/dhcpv6/duid.go
@@ -61,6 +61,9 @@ func (d *DUIDLLT) Equal(e DUID) bool {
if !ok {
return false
}
+ if d == nil {
+ return d == ellt
+ }
return d.HWType == ellt.HWType && d.Time == ellt.Time && bytes.Equal(d.LinkLayerAddr, ellt.LinkLayerAddr)
}
@@ -103,6 +106,9 @@ func (d *DUIDLL) Equal(e DUID) bool {
if !ok {
return false
}
+ if d == nil {
+ return d == ell
+ }
return d.HWType == ell.HWType && bytes.Equal(d.LinkLayerAddr, ell.LinkLayerAddr)
}
@@ -145,6 +151,9 @@ func (d *DUIDEN) Equal(e DUID) bool {
if !ok {
return false
}
+ if d == nil {
+ return d == en
+ }
return d.EnterpriseNumber == en.EnterpriseNumber && bytes.Equal(d.EnterpriseIdentifier, en.EnterpriseIdentifier)
}
@@ -187,6 +196,9 @@ func (d *DUIDUUID) Equal(e DUID) bool {
if !ok {
return false
}
+ if d == nil {
+ return d == euuid
+ }
return d.UUID == euuid.UUID
}
@@ -226,6 +238,9 @@ func (d *DUIDOpaque) Equal(e DUID) bool {
if !ok {
return false
}
+ if d == nil {
+ return d == eopaque
+ }
return d.Type == eopaque.Type && bytes.Equal(d.Data, eopaque.Data)
}
@@ -259,7 +274,7 @@ func (d DUIDType) String() string {
func DUIDFromBytes(data []byte) (DUID, error) {
buf := uio.NewBigEndianBuffer(data)
if !buf.Has(2) {
- return nil, fmt.Errorf("buffer too short: have %d bytes, want 2 bytes", buf.Len())
+ return nil, fmt.Errorf("%w: have %d bytes, want 2 bytes", uio.ErrBufferTooShort, buf.Len())
}
typ := DUIDType(buf.Read16())
diff --git a/dhcpv6/option_clientid_test.go b/dhcpv6/option_clientid_test.go
index dd637ae..a80403a 100644
--- a/dhcpv6/option_clientid_test.go
+++ b/dhcpv6/option_clientid_test.go
@@ -1,78 +1,108 @@
package dhcpv6
import (
+ "errors"
+ "fmt"
"net"
"reflect"
"testing"
+ "github.com/google/go-cmp/cmp"
"github.com/insomniacslk/dhcp/iana"
"github.com/stretchr/testify/require"
+ "github.com/u-root/uio/uio"
)
-func TestParseMessageOptionsWithClientID(t *testing.T) {
- buf := []byte{
- 0, 1, // Client ID option
- 0, 10, // length
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 0, 1, 2, 3, 4, 5, // HW addr
- }
-
- want := &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0, 1, 2, 3, 4, 5}}
- var mo MessageOptions
- if err := mo.FromBytes(buf); err != nil {
- t.Errorf("FromBytes = %v", err)
- } else if got := mo.ClientID(); !reflect.DeepEqual(got, want) {
- t.Errorf("ClientID = %v, want %v", got, want)
+func TestClientIDParseAndGetter(t *testing.T) {
+ for i, tt := range []struct {
+ buf []byte
+ err error
+ want DUID
+ }{
+ {
+ buf: []byte{
+ 0, 1, // Client ID option
+ 0, 10, // length
+ 0, 3, // DUID_LL
+ 0, 1, // hwtype ethernet
+ 0, 1, 2, 3, 4, 5, // HW addr
+ },
+ want: &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0, 1, 2, 3, 4, 5}},
+ },
+ {
+ buf: nil,
+ want: nil,
+ },
+ {
+ buf: []byte{0, 1, 0, 1, 0},
+ want: nil,
+ err: uio.ErrBufferTooShort,
+ },
+ } {
+ t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
+ var mo MessageOptions
+ if err := mo.FromBytes(tt.buf); !errors.Is(err, tt.err) {
+ t.Errorf("FromBytes = %v, want %v", err, tt.err)
+ }
+ if got := mo.ClientID(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("ClientID = %v, want %v", got, tt.want)
+ }
+ })
}
}
-func TestParseOptClientID(t *testing.T) {
- data := []byte{
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 0, 1, 2, 3, 4, 5, // hw addr
- }
- var opt optClientID
- err := opt.FromBytes(data)
- require.NoError(t, err)
- want := OptClientID(
- &DUIDLL{
- HWType: iana.HWTypeEthernet,
- LinkLayerAddr: net.HardwareAddr([]byte{0, 1, 2, 3, 4, 5}),
+func TestClientID(t *testing.T) {
+ for i, tt := range []struct {
+ buf []byte
+ want optClientID
+ err error
+ }{
+ {
+ buf: []byte{
+ 0, 3, // DUID_LL
+ 0, 1, // hwtype ethernet
+ 0, 1, 2, 3, 4, 5, // hw addr
+ },
+ want: optClientID{
+ &DUIDLL{
+ HWType: iana.HWTypeEthernet,
+ LinkLayerAddr: net.HardwareAddr([]byte{0, 1, 2, 3, 4, 5}),
+ },
+ },
},
- )
- require.Equal(t, want, &opt)
-}
-
-func TestOptClientIdToBytes(t *testing.T) {
- opt := OptClientID(
- &DUIDLL{
- HWType: iana.HWTypeEthernet,
- LinkLayerAddr: net.HardwareAddr([]byte{5, 4, 3, 2, 1, 0}),
+ {
+ buf: []byte{0},
+ err: uio.ErrBufferTooShort,
},
- )
- expected := []byte{
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 5, 4, 3, 2, 1, 0, // hw addr
- }
- require.Equal(t, expected, opt.ToBytes())
-}
+ {
+ buf: []byte{0, 3, 0},
+ err: uio.ErrBufferTooShort,
+ },
+ {
+ buf: nil,
+ err: uio.ErrBufferTooShort,
+ },
+ } {
+ t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
+ var opt optClientID
+ if err := opt.FromBytes(tt.buf); !errors.Is(err, tt.err) {
+ t.Errorf("FromBytes = %v, want %v", err, tt.err)
+ }
+ if tt.err == nil {
+ if !reflect.DeepEqual(tt.want, opt) {
+ t.Errorf("FromBytes = %v, want %v", opt, tt.want)
+ }
-func TestOptClientIdDecodeEncode(t *testing.T) {
- data := []byte{
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 5, 4, 3, 2, 1, 0, // hw addr
+ out := tt.want.ToBytes()
+ if diff := cmp.Diff(tt.buf, out); diff != "" {
+ t.Errorf("ToBytes mismatch: (-want, +got):\n%s", diff)
+ }
+ }
+ })
}
- var opt optClientID
- err := opt.FromBytes(data)
- require.NoError(t, err)
- require.Equal(t, data, opt.ToBytes())
}
-func TestOptionClientId(t *testing.T) {
+func TestOptionClientIDString(t *testing.T) {
opt := OptClientID(
&DUIDLL{
HWType: iana.HWTypeEthernet,
@@ -87,23 +117,3 @@ func TestOptionClientId(t *testing.T) {
"String() should contain the correct cid output",
)
}
-
-func TestOptClientIdparseOptClientIDBogusDUID(t *testing.T) {
- data := []byte{
- 0, 4, // DUID_UUID
- 1, 2, 3, 4, 5, 6, 7, 8, 9, // a UUID should be 18 bytes not 17
- 10, 11, 12, 13, 14, 15, 16, 17,
- }
- var opt optClientID
- err := opt.FromBytes(data)
- require.Error(t, err, "A truncated OptClientId DUID should return an error")
-}
-
-func TestOptClientIdparseOptClientIDInvalidTooShort(t *testing.T) {
- data := []byte{
- 0, // truncated: DUIDs are at least 2 bytes
- }
- var opt optClientID
- err := opt.FromBytes(data)
- require.Error(t, err, "A truncated OptClientId should return an error")
-}
diff --git a/dhcpv6/option_serverid_test.go b/dhcpv6/option_serverid_test.go
index b0250c2..bb4a928 100644
--- a/dhcpv6/option_serverid_test.go
+++ b/dhcpv6/option_serverid_test.go
@@ -1,82 +1,112 @@
package dhcpv6
import (
+ "errors"
+ "fmt"
"net"
"reflect"
"testing"
+ "github.com/google/go-cmp/cmp"
"github.com/insomniacslk/dhcp/iana"
"github.com/stretchr/testify/require"
+ "github.com/u-root/uio/uio"
)
-func TestParseMessageOptionsWithServerID(t *testing.T) {
- buf := []byte{
- 0, 2, // Server ID option
- 0, 10, // length
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 0, 1, 2, 3, 4, 5, // HW addr
- }
-
- want := &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0, 1, 2, 3, 4, 5}}
- var mo MessageOptions
- if err := mo.FromBytes(buf); err != nil {
- t.Errorf("FromBytes = %v", err)
- } else if got := mo.ServerID(); !reflect.DeepEqual(got, want) {
- t.Errorf("ServerID = %v, want %v", got, want)
+func TestServerIDParseAndGetter(t *testing.T) {
+ for i, tt := range []struct {
+ buf []byte
+ err error
+ want DUID
+ }{
+ {
+ buf: []byte{
+ 0, 2, // Server ID option
+ 0, 10, // length
+ 0, 3, // DUID_LL
+ 0, 1, // hwtype ethernet
+ 0, 1, 2, 3, 4, 5, // HW addr
+ },
+ want: &DUIDLL{HWType: iana.HWTypeEthernet, LinkLayerAddr: net.HardwareAddr{0, 1, 2, 3, 4, 5}},
+ },
+ {
+ buf: nil,
+ want: nil,
+ },
+ {
+ buf: []byte{0, 1, 0, 1, 0},
+ want: nil,
+ err: uio.ErrBufferTooShort,
+ },
+ } {
+ t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
+ var mo MessageOptions
+ if err := mo.FromBytes(tt.buf); !errors.Is(err, tt.err) {
+ t.Errorf("FromBytes = %v, want %v", err, tt.err)
+ }
+ if got := mo.ServerID(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("ServerID = %v, want %v", got, tt.want)
+ }
+ })
}
}
-func TestParseOptServerID(t *testing.T) {
- data := []byte{
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 0, 1, 2, 3, 4, 5, // hw addr
- }
- var opt optServerID
- err := opt.FromBytes(data)
- require.NoError(t, err)
- want := OptServerID(
- &DUIDLL{
- HWType: iana.HWTypeEthernet,
- LinkLayerAddr: net.HardwareAddr{0, 1, 2, 3, 4, 5},
+func TestServerID(t *testing.T) {
+ for i, tt := range []struct {
+ buf []byte
+ want optServerID
+ err error
+ }{
+ {
+ buf: []byte{
+ 0, 3, // DUID_LL
+ 0, 1, // hwtype ethernet
+ 0, 1, 2, 3, 4, 5, // hw addr
+ },
+ want: optServerID{
+ &DUIDLL{
+ HWType: iana.HWTypeEthernet,
+ LinkLayerAddr: net.HardwareAddr([]byte{0, 1, 2, 3, 4, 5}),
+ },
+ },
},
- )
- require.Equal(t, &opt, want)
-}
-
-func TestOptServerIdToBytes(t *testing.T) {
- opt := OptServerID(
- &DUIDLL{
- HWType: iana.HWTypeEthernet,
- LinkLayerAddr: net.HardwareAddr{5, 4, 3, 2, 1, 0},
+ {
+ buf: []byte{0},
+ err: uio.ErrBufferTooShort,
},
- )
- expected := []byte{
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 5, 4, 3, 2, 1, 0, // hw addr
- }
- require.Equal(t, expected, opt.ToBytes())
-}
+ {
+ buf: []byte{0, 3, 0},
+ err: uio.ErrBufferTooShort,
+ },
+ {
+ buf: nil,
+ err: uio.ErrBufferTooShort,
+ },
+ } {
+ t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
+ var opt optServerID
+ if err := opt.FromBytes(tt.buf); !errors.Is(err, tt.err) {
+ t.Errorf("FromBytes = %v, want %v", err, tt.err)
+ }
+ if tt.err == nil {
+ if !reflect.DeepEqual(tt.want, opt) {
+ t.Errorf("FromBytes = %v, want %v", opt, tt.want)
+ }
-func TestOptServerIdDecodeEncode(t *testing.T) {
- data := []byte{
- 0, 3, // DUID_LL
- 0, 1, // hwtype ethernet
- 5, 4, 3, 2, 1, 0, // hw addr
+ out := tt.want.ToBytes()
+ if diff := cmp.Diff(tt.buf, out); diff != "" {
+ t.Errorf("ToBytes mismatch: (-want, +got):\n%s", diff)
+ }
+ }
+ })
}
- var opt optServerID
- err := opt.FromBytes(data)
- require.NoError(t, err)
- require.Equal(t, data, opt.ToBytes())
}
-func TestOptionServerId(t *testing.T) {
+func TestOptionServerIDString(t *testing.T) {
opt := OptServerID(
&DUIDLL{
HWType: iana.HWTypeEthernet,
- LinkLayerAddr: net.HardwareAddr{0xde, 0xad, 0, 0, 0xbe, 0xef},
+ LinkLayerAddr: net.HardwareAddr([]byte{0xde, 0xad, 0, 0, 0xbe, 0xef}),
},
)
require.Equal(t, OptionServerID, opt.Code())
@@ -84,26 +114,6 @@ func TestOptionServerId(t *testing.T) {
t,
opt.String(),
"Server ID: DUID-LL{HWType=Ethernet HWAddr=de:ad:00:00:be:ef}",
- "String() should contain the correct sid output",
+ "String() should contain the correct cid output",
)
}
-
-func TestOptServerIdparseOptServerIDBogusDUID(t *testing.T) {
- data := []byte{
- 0, 4, // DUID_UUID
- 1, 2, 3, 4, 5, 6, 7, 8, 9, // a UUID should be 18 bytes not 17
- 10, 11, 12, 13, 14, 15, 16, 17,
- }
- var opt optServerID
- err := opt.FromBytes(data)
- require.Error(t, err, "A truncated OptServerId DUID should return an error")
-}
-
-func TestOptServerIdparseOptServerIDInvalidTooShort(t *testing.T) {
- data := []byte{
- 0, // truncated: DUIDs are at least 2 bytes
- }
- var opt optServerID
- err := opt.FromBytes(data)
- require.Error(t, err, "A truncated OptServerId should return an error")
-}
diff --git a/dhcpv6/options.go b/dhcpv6/options.go
index 6a55082..552abd0 100644
--- a/dhcpv6/options.go
+++ b/dhcpv6/options.go
@@ -224,7 +224,9 @@ type OptionParser func(code OptionCode, data []byte) (Option, error)
// FromBytesWithParser parses Options from byte sequences using the parsing
// function that is passed in as a paremeter
func (o *Options) FromBytesWithParser(data []byte, parser OptionParser) error {
- *o = make(Options, 0, 10)
+ if *o == nil {
+ *o = make(Options, 0, 10)
+ }
if len(data) == 0 {
// no options, no party
return nil
diff --git a/go.mod b/go.mod
index e484f33..90b005a 100644
--- a/go.mod
+++ b/go.mod
@@ -4,13 +4,14 @@ go 1.18
require (
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72
+ github.com/google/go-cmp v0.5.9
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7
github.com/mdlayher/netlink v1.1.1
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065
github.com/stretchr/testify v1.6.1
- github.com/u-root/uio v0.0.0-20230215032506-9aa6f7e2d72c
+ github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/sys v0.5.0
)
diff --git a/go.sum b/go.sum
index 52bea58..43f0b87 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
@@ -46,6 +48,8 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/u-root/uio v0.0.0-20230215032506-9aa6f7e2d72c h1:PHoGTnweZP+KIg/8Zc6+iOesrIF5yHkpb4GBDxHm7yE=
github.com/u-root/uio v0.0.0-20230215032506-9aa6f7e2d72c/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
+github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
+github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -77,6 +81,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=