summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv6/dhcpv6.go9
-rw-r--r--dhcpv6/dhcpv6_test.go34
-rw-r--r--dhcpv6/fuzz.go33
-rw-r--r--iana/hwtypes.go2
4 files changed, 72 insertions, 6 deletions
diff --git a/dhcpv6/dhcpv6.go b/dhcpv6/dhcpv6.go
index 7505dfc..4f7fbbb 100644
--- a/dhcpv6/dhcpv6.go
+++ b/dhcpv6/dhcpv6.go
@@ -46,6 +46,9 @@ func MessageFromBytes(data []byte) (*Message, error) {
MessageType: messageType,
}
buf.ReadBytes(d.TransactionID[:])
+ if buf.Error() != nil {
+ return nil, fmt.Errorf("Error parsing DHCPv6 header: %v", buf.Error())
+ }
if err := d.Options.FromBytes(buf.Data()); err != nil {
return nil, err
}
@@ -68,6 +71,9 @@ func RelayMessageFromBytes(data []byte) (*RelayMessage, error) {
d.LinkAddr = net.IP(buf.CopyN(net.IPv6len))
d.PeerAddr = net.IP(buf.CopyN(net.IPv6len))
+ if buf.Error() != nil {
+ return nil, fmt.Errorf("Error parsing RelayMessage header: %v", buf.Error())
+ }
// TODO: fail if no OptRelayMessage is present.
if err := d.Options.FromBytes(buf.Data()); err != nil {
return nil, err
@@ -79,6 +85,9 @@ func RelayMessageFromBytes(data []byte) (*RelayMessage, error) {
func FromBytes(data []byte) (DHCPv6, error) {
buf := uio.NewBigEndianBuffer(data)
messageType := MessageType(buf.Read8())
+ if buf.Error() != nil {
+ return nil, buf.Error()
+ }
if messageType == MessageTypeRelayForward || messageType == MessageTypeRelayReply {
return RelayMessageFromBytes(data)
diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go
index fbf7761..d097095 100644
--- a/dhcpv6/dhcpv6_test.go
+++ b/dhcpv6/dhcpv6_test.go
@@ -4,6 +4,7 @@ import (
"encoding/binary"
"errors"
"net"
+ "strconv"
"testing"
"github.com/insomniacslk/dhcp/iana"
@@ -129,11 +130,34 @@ func TestToBytes(t *testing.T) {
}
func TestFromAndToBytes(t *testing.T) {
- expected := []byte{01, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x00}
- d, err := FromBytes(expected)
- require.NoError(t, err)
- toBytes := d.ToBytes()
- require.Equal(t, expected, toBytes)
+ expected := [][]byte{
+ {01, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x00},
+ []byte("0000\x00\x01\x00\x0e\x00\x01000000000000"),
+ }
+ t.Parallel()
+ for i, packet := range expected {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ d, err := FromBytes(packet)
+ require.NoError(t, err)
+ toBytes := d.ToBytes()
+ require.Equal(t, packet, toBytes)
+ })
+ }
+}
+
+func TestFromBytesInvalid(t *testing.T) {
+ expected := [][]byte{
+ {},
+ {30},
+ {12},
+ }
+ t.Parallel()
+ for i, packet := range expected {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ _, err := FromBytes(packet)
+ require.Error(t, err)
+ })
+ }
}
func TestNewAdvertiseFromSolicit(t *testing.T) {
diff --git a/dhcpv6/fuzz.go b/dhcpv6/fuzz.go
new file mode 100644
index 0000000..3f5afef
--- /dev/null
+++ b/dhcpv6/fuzz.go
@@ -0,0 +1,33 @@
+// +build gofuzz
+
+package dhcpv6
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// Fuzz is an entrypoint for go-fuzz (github.com/dvyukov/go-fuzz)
+func Fuzz(data []byte) int {
+ msg, err := FromBytes(data)
+ if err != nil {
+ return 0
+ }
+
+ serialized := msg.ToBytes()
+ if !bytes.Equal(data, serialized) {
+ rtMsg, err := FromBytes(serialized)
+ fmt.Printf("Input: %x\n", data)
+ fmt.Printf("Round-trip: %x\n", serialized)
+ fmt.Println("Message: ", msg.Summary())
+ fmt.Printf("Go repr: %#v\n", msg)
+ fmt.Println("round-trip reserialized: ", rtMsg.Summary())
+ fmt.Printf("Go repr: %#v\n", rtMsg)
+ if err != nil {
+ fmt.Printf("failed to parse after deserialize-serialize: %v\n", err)
+ }
+ panic("round-trip different")
+ }
+
+ return 1
+}
diff --git a/iana/hwtypes.go b/iana/hwtypes.go
index bbb3188..e6fb38b 100644
--- a/iana/hwtypes.go
+++ b/iana/hwtypes.go
@@ -1,7 +1,7 @@
package iana
// HWType is a hardware type as per RFC 2132 and defined by the IANA.
-type HWType uint8
+type HWType uint16
// See IANA for values.
const (