syscall: fix IPv6 wrong network mask on latest FreeBSD

Looks like latest FreeBSD doesn't set address family identifer
for RTAX_NETMASK stuff; probably RTAX_GENMASK too, not confirmed.
This CL tries to identify address families by using the length of
each socket address if possible.

The issue is confirmed on FreeBSD 9.1.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/12332043
diff --git a/src/pkg/net/interface_test.go b/src/pkg/net/interface_test.go
index e31894a..17b28b6 100644
--- a/src/pkg/net/interface_test.go
+++ b/src/pkg/net/interface_test.go
@@ -108,12 +108,23 @@
 func testAddrs(t *testing.T, ifat []Addr) {
 	for _, ifa := range ifat {
 		switch ifa := ifa.(type) {
-		case *IPAddr, *IPNet:
+		case *IPAddr:
 			if ifa == nil {
 				t.Errorf("\tunexpected value: %v", ifa)
 			} else {
 				t.Logf("\tinterface address %q", ifa.String())
 			}
+		case *IPNet:
+			if ifa == nil {
+				t.Errorf("\tunexpected value: %v", ifa)
+			} else {
+				_, prefixLen := ifa.Mask.Size()
+				if ifa.IP.To4() != nil && prefixLen != 8*IPv4len || ifa.IP.To16() != nil && ifa.IP.To4() == nil && prefixLen != 8*IPv6len {
+					t.Errorf("\tunexpected value: %v, %v, %v, %v", ifa, ifa.IP, ifa.Mask, prefixLen)
+				} else {
+					t.Logf("\tinterface address %q", ifa.String())
+				}
+			}
 		default:
 			t.Errorf("\tunexpected type: %T", ifa)
 		}
diff --git a/src/pkg/syscall/route_bsd.go b/src/pkg/syscall/route_bsd.go
index 62c5ce1..2a81f85 100644
--- a/src/pkg/syscall/route_bsd.go
+++ b/src/pkg/syscall/route_bsd.go
@@ -156,7 +156,14 @@
 			sas = append(sas, sa)
 		case RTAX_NETMASK:
 			if rsa.Family == AF_UNSPEC {
-				rsa.Family = AF_INET // an old fasion, AF_UNSPEC means AF_INET
+				switch rsa.Len {
+				case SizeofSockaddrInet4:
+					rsa.Family = AF_INET
+				case SizeofSockaddrInet6:
+					rsa.Family = AF_INET6
+				default:
+					rsa.Family = AF_INET // an old fasion, AF_UNSPEC means AF_INET
+				}
 			}
 			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
 			if err != nil {