]> Cypherpunks repositories - gostls13.git/commitdiff
net: fix misidentification of link-local, global unicast IP addresses
authorMikio Hara <mikioh.mikioh@gmail.com>
Sat, 4 Jul 2015 04:49:47 +0000 (13:49 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Fri, 10 Jul 2015 07:30:33 +0000 (07:30 +0000)
Don't treat IPv4-mapped link-local IP addresses as IPv6 link-local
addresses, an IPv4 broadcast address as a global unicast IP address.

Fixes #11585.

Change-Id: I6a7a0c0601f18638f5c624ab63e12ee40f77b182
Reviewed-on: https://go-review.googlesource.com/11883
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/net/ip.go
src/net/ip_test.go

index a7f45642e37fbabb4448c23756fea1311ec5ff1b..cc004d607297c426a9c777bcb2b4bbe1d835fdee 100644 (file)
@@ -108,26 +108,23 @@ var (
 
 // IsUnspecified reports whether ip is an unspecified address.
 func (ip IP) IsUnspecified() bool {
-       if ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified) {
-               return true
-       }
-       return false
+       return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
 }
 
 // IsLoopback reports whether ip is a loopback address.
 func (ip IP) IsLoopback() bool {
-       if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
-               return true
+       if ip4 := ip.To4(); ip4 != nil {
+               return ip4[0] == 127
        }
        return ip.Equal(IPv6loopback)
 }
 
 // IsMulticast reports whether ip is a multicast address.
 func (ip IP) IsMulticast() bool {
-       if ip4 := ip.To4(); ip4 != nil && ip4[0]&0xf0 == 0xe0 {
-               return true
+       if ip4 := ip.To4(); ip4 != nil {
+               return ip4[0]&0xf0 == 0xe0
        }
-       return ip[0] == 0xff
+       return len(ip) == IPv6len && ip[0] == 0xff
 }
 
 // IsInterfaceLocalMulticast reports whether ip is
@@ -139,25 +136,27 @@ func (ip IP) IsInterfaceLocalMulticast() bool {
 // IsLinkLocalMulticast reports whether ip is a link-local
 // multicast address.
 func (ip IP) IsLinkLocalMulticast() bool {
-       if ip4 := ip.To4(); ip4 != nil && ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0 {
-               return true
+       if ip4 := ip.To4(); ip4 != nil {
+               return ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0
        }
-       return ip[0] == 0xff && ip[1]&0x0f == 0x02
+       return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x02
 }
 
 // IsLinkLocalUnicast reports whether ip is a link-local
 // unicast address.
 func (ip IP) IsLinkLocalUnicast() bool {
-       if ip4 := ip.To4(); ip4 != nil && ip4[0] == 169 && ip4[1] == 254 {
-               return true
+       if ip4 := ip.To4(); ip4 != nil {
+               return ip4[0] == 169 && ip4[1] == 254
        }
-       return ip[0] == 0xfe && ip[1]&0xc0 == 0x80
+       return len(ip) == IPv6len && ip[0] == 0xfe && ip[1]&0xc0 == 0x80
 }
 
 // IsGlobalUnicast reports whether ip is a global unicast
 // address.
 func (ip IP) IsGlobalUnicast() bool {
-       return !ip.IsUnspecified() &&
+       return (len(ip) == IPv4len || len(ip) == IPv6len) &&
+               !ip.Equal(IPv4bcast) &&
+               !ip.IsUnspecified() &&
                !ip.IsLoopback() &&
                !ip.IsMulticast() &&
                !ip.IsLinkLocalUnicast()
index 9c831d74b32aff716c70d22dae8f52c23d223701..554bb1eaa031bce397ea5dbb06d33afc4d82b6ad 100644 (file)
@@ -480,31 +480,44 @@ var ipAddrScopeTests = []struct {
        {IP.IsUnspecified, IPv4(127, 0, 0, 1), false},
        {IP.IsUnspecified, IPv6unspecified, true},
        {IP.IsUnspecified, IPv6interfacelocalallnodes, false},
+       {IP.IsUnspecified, nil, false},
        {IP.IsLoopback, IPv4(127, 0, 0, 1), true},
        {IP.IsLoopback, IPv4(127, 255, 255, 254), true},
        {IP.IsLoopback, IPv4(128, 1, 2, 3), false},
        {IP.IsLoopback, IPv6loopback, true},
        {IP.IsLoopback, IPv6linklocalallrouters, false},
+       {IP.IsLoopback, nil, false},
        {IP.IsMulticast, IPv4(224, 0, 0, 0), true},
        {IP.IsMulticast, IPv4(239, 0, 0, 0), true},
        {IP.IsMulticast, IPv4(240, 0, 0, 0), false},
        {IP.IsMulticast, IPv6linklocalallnodes, true},
        {IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
        {IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+       {IP.IsMulticast, nil, false},
+       {IP.IsInterfaceLocalMulticast, IPv4(224, 0, 0, 0), false},
+       {IP.IsInterfaceLocalMulticast, IPv4(0xff, 0x01, 0, 0), false},
+       {IP.IsInterfaceLocalMulticast, IPv6interfacelocalallnodes, true},
+       {IP.IsInterfaceLocalMulticast, nil, false},
        {IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true},
        {IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false},
+       {IP.IsLinkLocalMulticast, IPv4(0xff, 0x02, 0, 0), false},
        {IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true},
        {IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+       {IP.IsLinkLocalMulticast, nil, false},
        {IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true},
        {IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false},
+       {IP.IsLinkLocalUnicast, IPv4(0xfe, 0x80, 0, 0), false},
        {IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
        {IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+       {IP.IsLinkLocalUnicast, nil, false},
        {IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true},
        {IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false},
        {IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false},
+       {IP.IsGlobalUnicast, IPv4bcast, false},
        {IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true},
        {IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
        {IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+       {IP.IsGlobalUnicast, nil, false},
 }
 
 func name(f interface{}) string {
@@ -516,5 +529,12 @@ func TestIPAddrScope(t *testing.T) {
                if ok := tt.scope(tt.in); ok != tt.ok {
                        t.Errorf("%s(%q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok)
                }
+               ip := tt.in.To4()
+               if ip == nil {
+                       continue
+               }
+               if ok := tt.scope(ip); ok != tt.ok {
+                       t.Errorf("%s(%q) = %v, want %v", name(tt.scope), ip, ok, tt.ok)
+               }
        }
 }