diff --git a/route/address.go b/route/address.go
index 5443d6722..bae63003f 100644
--- a/route/address.go
+++ b/route/address.go
@@ -170,20 +170,37 @@ func (a *Inet6Addr) marshal(b []byte) (int, error) {
 
 // parseInetAddr parses b as an internet address for IPv4 or IPv6.
 func parseInetAddr(af int, b []byte) (Addr, error) {
+	const (
+		off4 = 4 // offset of in_addr
+		off6 = 8 // offset of in6_addr
+	)
 	switch af {
 	case syscall.AF_INET:
-		if len(b) < sizeofSockaddrInet {
+		if len(b) < (off4+1) || len(b) < int(b[0]) {
 			return nil, errInvalidAddr
 		}
+		sockAddrLen := int(b[0])
 		a := &Inet4Addr{}
-		copy(a.IP[:], b[4:8])
+		n := off4 + 4
+		if sockAddrLen < n {
+			n = sockAddrLen
+		}
+		copy(a.IP[:], b[off4:n])
 		return a, nil
 	case syscall.AF_INET6:
-		if len(b) < sizeofSockaddrInet6 {
+		if len(b) < (off6+1) || len(b) < int(b[0]) {
 			return nil, errInvalidAddr
 		}
-		a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
-		copy(a.IP[:], b[8:24])
+		sockAddrLen := int(b[0])
+		n := off6 + 16
+		if sockAddrLen < n {
+			n = sockAddrLen
+		}
+		a := &Inet6Addr{}
+		if sockAddrLen == sizeofSockaddrInet6 {
+			a.ZoneID = int(nativeEndian.Uint32(b[24:28]))
+		}
+		copy(a.IP[:], b[off6:n])
 		if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
 			// KAME based IPv6 protocol stack usually
 			// embeds the interface index in the
diff --git a/route/address_darwin_test.go b/route/address_darwin_test.go
index b819183a7..0b5c72d1d 100644
--- a/route/address_darwin_test.go
+++ b/route/address_darwin_test.go
@@ -42,6 +42,60 @@ var parseAddrsOnDarwinLittleEndianTests = []parseAddrsOnDarwinTest{
 			nil,
 		},
 	},
+	{
+		syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK,
+		parseKernelInetAddr,
+		[]byte{
+			0x10, 0x02, 0x00, 0x00, 0x64, 0x71, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+			0x14, 0x12, 0x21, 0x00, 0x01, 0x08, 0x00, 0x00,
+			0x75, 0x74, 0x75, 0x6e, 0x34, 0x33, 0x31, 0x39,
+			0x00, 0x00, 0x00, 0x00,
+
+			0x06, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+		},
+		[]Addr{
+			&Inet4Addr{IP: [4]byte{100, 113, 0, 0}},
+			&LinkAddr{Index: 33, Name: "utun4319"},
+			&Inet4Addr{IP: [4]byte{255, 255, 0, 0}},
+			nil,
+			nil,
+			nil,
+			nil,
+			nil,
+		},
+	},
+	// route -n add -inet6 fd84:1b4e:6281:: -prefixlen 48 fe80::f22f:4bff:fe09:3bff%utun4319
+	// gw fe80:0000:0000:0000:f22f:4bff:fe09:3bff
+	{
+		syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK,
+		parseKernelInetAddr,
+		[]byte{
+			0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0xfd, 0x84, 0x1b, 0x4e, 0x62, 0x81, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00,
+
+			0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0xfe, 0x80, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00,
+			0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff,
+			0x00, 0x00, 0x00, 0x00,
+
+			0x0e, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+		},
+		[]Addr{
+			&Inet6Addr{IP: [16]byte{ 0xfd, 0x84, 0x1b, 0x4e, 0x62, 0x81 }},
+			&Inet6Addr{IP: [16]byte{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff }, ZoneID: 33},
+			&Inet6Addr{IP: [16]byte{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,}},
+			nil,
+			nil,
+			nil,
+			nil,
+			nil,
+		},
+	},
 }
 
 func TestParseAddrsOnDarwin(t *testing.T) {