Russ Cox | 83348f9 | 2008-12-18 15:42:39 -0800 | [diff] [blame] | 1 | // Copyright 2009 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package net |
| 6 | |
| 7 | import ( |
Mikio Hara | 1f54410 | 2016-04-07 17:19:29 +0900 | [diff] [blame] | 8 | "bytes" |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 9 | "reflect" |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 10 | "runtime" |
Russ Cox | 965845a | 2011-11-02 15:54:16 -0400 | [diff] [blame] | 11 | "testing" |
Russ Cox | 83348f9 | 2008-12-18 15:42:39 -0800 | [diff] [blame] | 12 | ) |
| 13 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 14 | var parseIPTests = []struct { |
Robert Griesemer | a3d1045 | 2009-12-15 15:35:38 -0800 | [diff] [blame] | 15 | in string |
| 16 | out IP |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 17 | }{ |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 18 | {"127.0.1.2", IPv4(127, 0, 1, 2)}, |
| 19 | {"127.0.0.1", IPv4(127, 0, 0, 1)}, |
Mikio Hara | 2958860 | 2014-12-31 16:46:19 +0900 | [diff] [blame] | 20 | {"127.001.002.003", IPv4(127, 1, 2, 3)}, |
| 21 | {"::ffff:127.1.2.3", IPv4(127, 1, 2, 3)}, |
| 22 | {"::ffff:127.001.002.003", IPv4(127, 1, 2, 3)}, |
| 23 | {"::ffff:7f01:0203", IPv4(127, 1, 2, 3)}, |
| 24 | {"0:0:0:0:0000:ffff:127.1.2.3", IPv4(127, 1, 2, 3)}, |
| 25 | {"0:0:0:0:000000:ffff:127.1.2.3", IPv4(127, 1, 2, 3)}, |
| 26 | {"0:0:0:0::ffff:127.1.2.3", IPv4(127, 1, 2, 3)}, |
| 27 | |
| 28 | {"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}}, |
| 29 | {"2001:4860:0000:2001:0000:0000:0000:0068", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}}, |
| 30 | |
Joe Tsai | 3ef0e8f | 2016-09-02 01:14:57 -0700 | [diff] [blame] | 31 | {"-0.0.0.0", nil}, |
| 32 | {"0.-1.0.0", nil}, |
| 33 | {"0.0.-2.0", nil}, |
| 34 | {"0.0.0.-3", nil}, |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 35 | {"127.0.0.256", nil}, |
| 36 | {"abc", nil}, |
Quan Yong Zhai | c09af66 | 2011-04-14 23:49:51 -0400 | [diff] [blame] | 37 | {"123:", nil}, |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 38 | {"fe80::1%lo0", nil}, |
| 39 | {"fe80::1%911", nil}, |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 40 | {"", nil}, |
Alex A Skinner | 487dff1 | 2013-12-20 21:29:28 +0900 | [diff] [blame] | 41 | {"a1:a2:a3:a4::b1:b2:b3:b4", nil}, // Issue 6628 |
Russ Cox | be2edb5 | 2009-03-03 08:39:12 -0800 | [diff] [blame] | 42 | } |
Russ Cox | 83348f9 | 2008-12-18 15:42:39 -0800 | [diff] [blame] | 43 | |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 44 | func TestParseIP(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 45 | for _, tt := range parseIPTests { |
| 46 | if out := ParseIP(tt.in); !reflect.DeepEqual(out, tt.out) { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 47 | t.Errorf("ParseIP(%q) = %v, want %v", tt.in, out, tt.out) |
Russ Cox | 83348f9 | 2008-12-18 15:42:39 -0800 | [diff] [blame] | 48 | } |
Brad Fitzpatrick | da7a51d | 2013-09-06 15:29:09 -0700 | [diff] [blame] | 49 | if tt.in == "" { |
| 50 | // Tested in TestMarshalEmptyIP below. |
| 51 | continue |
| 52 | } |
Russ Cox | 413d4c6 | 2013-08-14 00:33:20 -0400 | [diff] [blame] | 53 | var out IP |
Russ Cox | 413d4c6 | 2013-08-14 00:33:20 -0400 | [diff] [blame] | 54 | if err := out.UnmarshalText([]byte(tt.in)); !reflect.DeepEqual(out, tt.out) || (tt.out == nil) != (err != nil) { |
| 55 | t.Errorf("IP.UnmarshalText(%q) = %v, %v, want %v", tt.in, out, err, tt.out) |
| 56 | } |
Russ Cox | 83348f9 | 2008-12-18 15:42:39 -0800 | [diff] [blame] | 57 | } |
| 58 | } |
Mikio Hara | e41987c | 2010-08-12 00:03:01 -0700 | [diff] [blame] | 59 | |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 60 | func TestLookupWithIP(t *testing.T) { |
| 61 | _, err := LookupIP("") |
| 62 | if err == nil { |
| 63 | t.Errorf(`LookupIP("") succeeded, should fail`) |
| 64 | } |
| 65 | _, err = LookupHost("") |
| 66 | if err == nil { |
| 67 | t.Errorf(`LookupIP("") succeeded, should fail`) |
| 68 | } |
| 69 | |
| 70 | // Test that LookupHost and LookupIP, which normally |
| 71 | // expect host names, work with IP addresses. |
| 72 | for _, tt := range parseIPTests { |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 73 | if tt.out != nil { |
Russ Cox | 5201bf7 | 2015-07-20 22:16:29 -0400 | [diff] [blame] | 74 | addrs, err := LookupHost(tt.in) |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 75 | if len(addrs) != 1 || addrs[0] != tt.in || err != nil { |
| 76 | t.Errorf("LookupHost(%q) = %v, %v, want %v, nil", tt.in, addrs, err, []string{tt.in}) |
| 77 | } |
Russ Cox | 5201bf7 | 2015-07-20 22:16:29 -0400 | [diff] [blame] | 78 | } else if !testing.Short() { |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 79 | // We can't control what the host resolver does; if it can resolve, say, |
| 80 | // 127.0.0.256 or fe80::1%911 or a host named 'abc', who are we to judge? |
| 81 | // Warn about these discrepancies but don't fail the test. |
Russ Cox | 5201bf7 | 2015-07-20 22:16:29 -0400 | [diff] [blame] | 82 | addrs, err := LookupHost(tt.in) |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 83 | if err == nil { |
| 84 | t.Logf("warning: LookupHost(%q) = %v, want error", tt.in, addrs) |
| 85 | } |
| 86 | } |
| 87 | |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 88 | if tt.out != nil { |
Russ Cox | 5201bf7 | 2015-07-20 22:16:29 -0400 | [diff] [blame] | 89 | ips, err := LookupIP(tt.in) |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 90 | if len(ips) != 1 || !reflect.DeepEqual(ips[0], tt.out) || err != nil { |
| 91 | t.Errorf("LookupIP(%q) = %v, %v, want %v, nil", tt.in, ips, err, []IP{tt.out}) |
| 92 | } |
Russ Cox | 5201bf7 | 2015-07-20 22:16:29 -0400 | [diff] [blame] | 93 | } else if !testing.Short() { |
| 94 | ips, err := LookupIP(tt.in) |
Russ Cox | 222b23a | 2015-06-24 08:39:44 -0400 | [diff] [blame] | 95 | // We can't control what the host resolver does. See above. |
| 96 | if err == nil { |
| 97 | t.Logf("warning: LookupIP(%q) = %v, want error", tt.in, ips) |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 103 | func BenchmarkParseIP(b *testing.B) { |
Mikio Hara | ef54930 | 2015-05-14 09:25:24 +0900 | [diff] [blame] | 104 | testHookUninstaller.Do(uninstallTestHooks) |
Mikio Hara | 29d1f3b | 2015-03-01 12:27:01 +0900 | [diff] [blame] | 105 | |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 106 | for i := 0; i < b.N; i++ { |
| 107 | for _, tt := range parseIPTests { |
| 108 | ParseIP(tt.in) |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | |
Brad Fitzpatrick | da7a51d | 2013-09-06 15:29:09 -0700 | [diff] [blame] | 113 | // Issue 6339 |
| 114 | func TestMarshalEmptyIP(t *testing.T) { |
| 115 | for _, in := range [][]byte{nil, []byte("")} { |
| 116 | var out = IP{1, 2, 3, 4} |
| 117 | if err := out.UnmarshalText(in); err != nil || out != nil { |
| 118 | t.Errorf("UnmarshalText(%v) = %v, %v; want nil, nil", in, out, err) |
| 119 | } |
| 120 | } |
| 121 | var ip IP |
| 122 | got, err := ip.MarshalText() |
| 123 | if err != nil { |
| 124 | t.Fatal(err) |
| 125 | } |
| 126 | if !reflect.DeepEqual(got, []byte("")) { |
| 127 | t.Errorf(`got %#v, want []byte("")`, got) |
| 128 | } |
| 129 | } |
| 130 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 131 | var ipStringTests = []struct { |
Mikio Hara | 1f54410 | 2016-04-07 17:19:29 +0900 | [diff] [blame] | 132 | in IP // see RFC 791 and RFC 4291 |
| 133 | str string // see RFC 791, RFC 4291 and RFC 5952 |
| 134 | byt []byte |
| 135 | error |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 136 | }{ |
Mikio Hara | 1f54410 | 2016-04-07 17:19:29 +0900 | [diff] [blame] | 137 | // IPv4 address |
| 138 | { |
| 139 | IP{192, 0, 2, 1}, |
| 140 | "192.0.2.1", |
| 141 | []byte("192.0.2.1"), |
| 142 | nil, |
| 143 | }, |
| 144 | { |
| 145 | IP{0, 0, 0, 0}, |
| 146 | "0.0.0.0", |
| 147 | []byte("0.0.0.0"), |
| 148 | nil, |
| 149 | }, |
| 150 | |
| 151 | // IPv4-mapped IPv6 address |
| 152 | { |
| 153 | IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 0, 2, 1}, |
| 154 | "192.0.2.1", |
| 155 | []byte("192.0.2.1"), |
| 156 | nil, |
| 157 | }, |
| 158 | { |
| 159 | IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0}, |
| 160 | "0.0.0.0", |
| 161 | []byte("0.0.0.0"), |
| 162 | nil, |
| 163 | }, |
| 164 | |
| 165 | // IPv6 address |
| 166 | { |
| 167 | IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, |
| 168 | "2001:db8::123:12:1", |
| 169 | []byte("2001:db8::123:12:1"), |
| 170 | nil, |
| 171 | }, |
| 172 | { |
| 173 | IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1}, |
| 174 | "2001:db8::1", |
| 175 | []byte("2001:db8::1"), |
| 176 | nil, |
| 177 | }, |
| 178 | { |
| 179 | IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1}, |
| 180 | "2001:db8:0:1:0:1:0:1", |
| 181 | []byte("2001:db8:0:1:0:1:0:1"), |
| 182 | nil, |
| 183 | }, |
| 184 | { |
| 185 | IP{0x20, 0x1, 0xd, 0xb8, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0}, |
| 186 | "2001:db8:1:0:1:0:1:0", |
| 187 | []byte("2001:db8:1:0:1:0:1:0"), |
| 188 | nil, |
| 189 | }, |
| 190 | { |
| 191 | IP{0x20, 0x1, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, |
| 192 | "2001::1:0:0:1", |
| 193 | []byte("2001::1:0:0:1"), |
| 194 | nil, |
| 195 | }, |
| 196 | { |
| 197 | IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0}, |
| 198 | "2001:db8:0:0:1::", |
| 199 | []byte("2001:db8:0:0:1::"), |
| 200 | nil, |
| 201 | }, |
| 202 | { |
| 203 | IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, |
| 204 | "2001:db8::1:0:0:1", |
| 205 | []byte("2001:db8::1:0:0:1"), |
| 206 | nil, |
| 207 | }, |
| 208 | { |
| 209 | IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0xa, 0, 0xb, 0, 0xc, 0, 0xd}, |
| 210 | "2001:db8::a:b:c:d", |
| 211 | []byte("2001:db8::a:b:c:d"), |
| 212 | nil, |
| 213 | }, |
| 214 | { |
| 215 | IPv6unspecified, |
| 216 | "::", |
| 217 | []byte("::"), |
| 218 | nil, |
| 219 | }, |
| 220 | |
| 221 | // IP wildcard equivalent address in Dial/Listen API |
| 222 | { |
| 223 | nil, |
| 224 | "<nil>", |
| 225 | nil, |
| 226 | nil, |
| 227 | }, |
| 228 | |
| 229 | // Opaque byte sequence |
| 230 | { |
| 231 | IP{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, |
Russ Cox | 7f9255c | 2016-05-23 20:40:52 -0400 | [diff] [blame] | 232 | "?0123456789abcdef", |
Mikio Hara | 1f54410 | 2016-04-07 17:19:29 +0900 | [diff] [blame] | 233 | nil, |
| 234 | &AddrError{Err: "invalid IP address", Addr: "0123456789abcdef"}, |
| 235 | }, |
Mikio Hara | e41987c | 2010-08-12 00:03:01 -0700 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | func TestIPString(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 239 | for _, tt := range ipStringTests { |
Mikio Hara | 1f54410 | 2016-04-07 17:19:29 +0900 | [diff] [blame] | 240 | if out := tt.in.String(); out != tt.str { |
| 241 | t.Errorf("IP.String(%v) = %q, want %q", tt.in, out, tt.str) |
Brad Fitzpatrick | da7a51d | 2013-09-06 15:29:09 -0700 | [diff] [blame] | 242 | } |
Mikio Hara | 1f54410 | 2016-04-07 17:19:29 +0900 | [diff] [blame] | 243 | if out, err := tt.in.MarshalText(); !bytes.Equal(out, tt.byt) || !reflect.DeepEqual(err, tt.error) { |
| 244 | t.Errorf("IP.MarshalText(%v) = %v, %v, want %v, %v", tt.in, out, err, tt.byt, tt.error) |
Russ Cox | 413d4c6 | 2013-08-14 00:33:20 -0400 | [diff] [blame] | 245 | } |
Mikio Hara | e41987c | 2010-08-12 00:03:01 -0700 | [diff] [blame] | 246 | } |
| 247 | } |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 248 | |
Josh Bleecher Snyder | 40cf4ad | 2016-07-07 15:32:49 -0700 | [diff] [blame] | 249 | var sink string |
| 250 | |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 251 | func BenchmarkIPString(b *testing.B) { |
Mikio Hara | ef54930 | 2015-05-14 09:25:24 +0900 | [diff] [blame] | 252 | testHookUninstaller.Do(uninstallTestHooks) |
Mikio Hara | 29d1f3b | 2015-03-01 12:27:01 +0900 | [diff] [blame] | 253 | |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 254 | for i := 0; i < b.N; i++ { |
| 255 | for _, tt := range ipStringTests { |
| 256 | if tt.in != nil { |
Josh Bleecher Snyder | 40cf4ad | 2016-07-07 15:32:49 -0700 | [diff] [blame] | 257 | sink = tt.in.String() |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 258 | } |
| 259 | } |
| 260 | } |
| 261 | } |
| 262 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 263 | var ipMaskTests = []struct { |
Mikio Hara | 683df29 | 2011-08-29 10:49:03 -0400 | [diff] [blame] | 264 | in IP |
| 265 | mask IPMask |
| 266 | out IP |
| 267 | }{ |
| 268 | {IPv4(192, 168, 1, 127), IPv4Mask(255, 255, 255, 128), IPv4(192, 168, 1, 0)}, |
| 269 | {IPv4(192, 168, 1, 127), IPMask(ParseIP("255.255.255.192")), IPv4(192, 168, 1, 64)}, |
| 270 | {IPv4(192, 168, 1, 127), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0")), IPv4(192, 168, 1, 96)}, |
| 271 | {IPv4(192, 168, 1, 127), IPv4Mask(255, 0, 255, 0), IPv4(192, 0, 1, 0)}, |
| 272 | {ParseIP("2001:db8::1"), IPMask(ParseIP("ffff:ff80::")), ParseIP("2001:d80::")}, |
| 273 | {ParseIP("2001:db8::1"), IPMask(ParseIP("f0f0:0f0f::")), ParseIP("2000:d08::")}, |
| 274 | } |
| 275 | |
| 276 | func TestIPMask(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 277 | for _, tt := range ipMaskTests { |
Mikio Hara | 683df29 | 2011-08-29 10:49:03 -0400 | [diff] [blame] | 278 | if out := tt.in.Mask(tt.mask); out == nil || !tt.out.Equal(out) { |
| 279 | t.Errorf("IP(%v).Mask(%v) = %v, want %v", tt.in, tt.mask, out, tt.out) |
| 280 | } |
| 281 | } |
| 282 | } |
| 283 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 284 | var ipMaskStringTests = []struct { |
Mikio Hara | 683df29 | 2011-08-29 10:49:03 -0400 | [diff] [blame] | 285 | in IPMask |
| 286 | out string |
| 287 | }{ |
| 288 | {IPv4Mask(255, 255, 255, 240), "fffffff0"}, |
| 289 | {IPv4Mask(255, 0, 128, 0), "ff008000"}, |
| 290 | {IPMask(ParseIP("ffff:ff80::")), "ffffff80000000000000000000000000"}, |
| 291 | {IPMask(ParseIP("ef00:ff80::cafe:0")), "ef00ff800000000000000000cafe0000"}, |
| 292 | {nil, "<nil>"}, |
| 293 | } |
| 294 | |
| 295 | func TestIPMaskString(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 296 | for _, tt := range ipMaskStringTests { |
Mikio Hara | 683df29 | 2011-08-29 10:49:03 -0400 | [diff] [blame] | 297 | if out := tt.in.String(); out != tt.out { |
| 298 | t.Errorf("IPMask.String(%v) = %q, want %q", tt.in, out, tt.out) |
| 299 | } |
| 300 | } |
| 301 | } |
| 302 | |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 303 | func BenchmarkIPMaskString(b *testing.B) { |
Mikio Hara | ef54930 | 2015-05-14 09:25:24 +0900 | [diff] [blame] | 304 | testHookUninstaller.Do(uninstallTestHooks) |
Mikio Hara | 29d1f3b | 2015-03-01 12:27:01 +0900 | [diff] [blame] | 305 | |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 306 | for i := 0; i < b.N; i++ { |
| 307 | for _, tt := range ipMaskStringTests { |
Josh Bleecher Snyder | 40cf4ad | 2016-07-07 15:32:49 -0700 | [diff] [blame] | 308 | sink = tt.in.String() |
Rui Ueyama | f7c99f3 | 2014-06-11 20:40:00 -0700 | [diff] [blame] | 309 | } |
| 310 | } |
| 311 | } |
| 312 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 313 | var parseCIDRTests = []struct { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 314 | in string |
| 315 | ip IP |
| 316 | net *IPNet |
Russ Cox | eb69292 | 2011-11-01 22:05:34 -0400 | [diff] [blame] | 317 | err error |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 318 | }{ |
Mikio Hara | e8cf49f | 2012-11-27 00:45:42 +0900 | [diff] [blame] | 319 | {"135.104.0.0/32", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 255)}, nil}, |
| 320 | {"0.0.0.0/24", IPv4(0, 0, 0, 0), &IPNet{IP: IPv4(0, 0, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil}, |
| 321 | {"135.104.0.0/24", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil}, |
| 322 | {"135.104.0.1/32", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 1), Mask: IPv4Mask(255, 255, 255, 255)}, nil}, |
| 323 | {"135.104.0.1/24", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil}, |
| 324 | {"::1/128", ParseIP("::1"), &IPNet{IP: ParseIP("::1"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))}, nil}, |
| 325 | {"abcd:2345::/127", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"))}, nil}, |
| 326 | {"abcd:2345::/65", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:8000::"))}, nil}, |
| 327 | {"abcd:2345::/64", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff::"))}, nil}, |
| 328 | {"abcd:2345::/63", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:fffe::"))}, nil}, |
| 329 | {"abcd:2345::/33", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:8000::"))}, nil}, |
| 330 | {"abcd:2345::/32", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff::"))}, nil}, |
| 331 | {"abcd:2344::/31", ParseIP("abcd:2344::"), &IPNet{IP: ParseIP("abcd:2344::"), Mask: IPMask(ParseIP("ffff:fffe::"))}, nil}, |
| 332 | {"abcd:2300::/24", ParseIP("abcd:2300::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil}, |
| 333 | {"abcd:2345::/24", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil}, |
| 334 | {"2001:DB8::/48", ParseIP("2001:DB8::"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil}, |
| 335 | {"2001:DB8::1/48", ParseIP("2001:DB8::1"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil}, |
Mikio Hara | 055ecb7 | 2015-04-21 21:20:15 +0900 | [diff] [blame] | 336 | {"192.168.1.1/255.255.255.0", nil, nil, &ParseError{Type: "CIDR address", Text: "192.168.1.1/255.255.255.0"}}, |
| 337 | {"192.168.1.1/35", nil, nil, &ParseError{Type: "CIDR address", Text: "192.168.1.1/35"}}, |
| 338 | {"2001:db8::1/-1", nil, nil, &ParseError{Type: "CIDR address", Text: "2001:db8::1/-1"}}, |
Joe Tsai | 3ef0e8f | 2016-09-02 01:14:57 -0700 | [diff] [blame] | 339 | {"2001:db8::1/-0", nil, nil, &ParseError{Type: "CIDR address", Text: "2001:db8::1/-0"}}, |
| 340 | {"-0.0.0.0/32", nil, nil, &ParseError{Type: "CIDR address", Text: "-0.0.0.0/32"}}, |
| 341 | {"0.-1.0.0/32", nil, nil, &ParseError{Type: "CIDR address", Text: "0.-1.0.0/32"}}, |
| 342 | {"0.0.-2.0/32", nil, nil, &ParseError{Type: "CIDR address", Text: "0.0.-2.0/32"}}, |
| 343 | {"0.0.0.-3/32", nil, nil, &ParseError{Type: "CIDR address", Text: "0.0.0.-3/32"}}, |
| 344 | {"0.0.0.0/-0", nil, nil, &ParseError{Type: "CIDR address", Text: "0.0.0.0/-0"}}, |
Mikio Hara | 055ecb7 | 2015-04-21 21:20:15 +0900 | [diff] [blame] | 345 | {"", nil, nil, &ParseError{Type: "CIDR address", Text: ""}}, |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 346 | } |
| 347 | |
| 348 | func TestParseCIDR(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 349 | for _, tt := range parseCIDRTests { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 350 | ip, net, err := ParseCIDR(tt.in) |
| 351 | if !reflect.DeepEqual(err, tt.err) { |
| 352 | t.Errorf("ParseCIDR(%q) = %v, %v; want %v, %v", tt.in, ip, net, tt.ip, tt.net) |
| 353 | } |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 354 | if err == nil && (!tt.ip.Equal(ip) || !tt.net.IP.Equal(net.IP) || !reflect.DeepEqual(net.Mask, tt.net.Mask)) { |
| 355 | t.Errorf("ParseCIDR(%q) = %v, {%v, %v}; want %v, {%v, %v}", tt.in, ip, net.IP, net.Mask, tt.ip, tt.net.IP, tt.net.Mask) |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 356 | } |
| 357 | } |
| 358 | } |
| 359 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 360 | var ipNetContainsTests = []struct { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 361 | ip IP |
| 362 | net *IPNet |
| 363 | ok bool |
| 364 | }{ |
Mikio Hara | e8cf49f | 2012-11-27 00:45:42 +0900 | [diff] [blame] | 365 | {IPv4(172, 16, 1, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(12, 32)}, true}, |
| 366 | {IPv4(172, 24, 0, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(13, 32)}, false}, |
| 367 | {IPv4(192, 168, 0, 3), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 0, 255, 252)}, true}, |
| 368 | {IPv4(192, 168, 0, 4), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 255, 0, 252)}, false}, |
| 369 | {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: CIDRMask(47, 128)}, true}, |
| 370 | {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:2::"), Mask: CIDRMask(47, 128)}, false}, |
| 371 | {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("ffff:0:ffff::"))}, true}, |
| 372 | {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("0:0:0:ffff::"))}, false}, |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 373 | } |
| 374 | |
| 375 | func TestIPNetContains(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 376 | for _, tt := range ipNetContainsTests { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 377 | if ok := tt.net.Contains(tt.ip); ok != tt.ok { |
| 378 | t.Errorf("IPNet(%v).Contains(%v) = %v, want %v", tt.net, tt.ip, ok, tt.ok) |
| 379 | } |
| 380 | } |
| 381 | } |
| 382 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 383 | var ipNetStringTests = []struct { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 384 | in *IPNet |
| 385 | out string |
| 386 | }{ |
Mikio Hara | e8cf49f | 2012-11-27 00:45:42 +0900 | [diff] [blame] | 387 | {&IPNet{IP: IPv4(192, 168, 1, 0), Mask: CIDRMask(26, 32)}, "192.168.1.0/26"}, |
| 388 | {&IPNet{IP: IPv4(192, 168, 1, 0), Mask: IPv4Mask(255, 0, 255, 0)}, "192.168.1.0/ff00ff00"}, |
| 389 | {&IPNet{IP: ParseIP("2001:db8::"), Mask: CIDRMask(55, 128)}, "2001:db8::/55"}, |
| 390 | {&IPNet{IP: ParseIP("2001:db8::"), Mask: IPMask(ParseIP("8000:f123:0:cafe::"))}, "2001:db8::/8000f1230000cafe0000000000000000"}, |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 391 | } |
| 392 | |
| 393 | func TestIPNetString(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 394 | for _, tt := range ipNetStringTests { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 395 | if out := tt.in.String(); out != tt.out { |
| 396 | t.Errorf("IPNet.String(%v) = %q, want %q", tt.in, out, tt.out) |
| 397 | } |
| 398 | } |
| 399 | } |
| 400 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 401 | var cidrMaskTests = []struct { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 402 | ones int |
| 403 | bits int |
| 404 | out IPMask |
| 405 | }{ |
| 406 | {0, 32, IPv4Mask(0, 0, 0, 0)}, |
| 407 | {12, 32, IPv4Mask(255, 240, 0, 0)}, |
| 408 | {24, 32, IPv4Mask(255, 255, 255, 0)}, |
| 409 | {32, 32, IPv4Mask(255, 255, 255, 255)}, |
| 410 | {0, 128, IPMask{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, |
| 411 | {4, 128, IPMask{0xf0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, |
| 412 | {48, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, |
| 413 | {128, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, |
| 414 | {33, 32, nil}, |
| 415 | {32, 33, nil}, |
| 416 | {-1, 128, nil}, |
| 417 | {128, -1, nil}, |
| 418 | } |
| 419 | |
| 420 | func TestCIDRMask(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 421 | for _, tt := range cidrMaskTests { |
| 422 | if out := CIDRMask(tt.ones, tt.bits); !reflect.DeepEqual(out, tt.out) { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 423 | t.Errorf("CIDRMask(%v, %v) = %v, want %v", tt.ones, tt.bits, out, tt.out) |
| 424 | } |
| 425 | } |
| 426 | } |
| 427 | |
| 428 | var ( |
| 429 | v4addr = IP{192, 168, 0, 1} |
| 430 | v4mappedv6addr = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 0, 1} |
| 431 | v6addr = IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1} |
| 432 | v4mask = IPMask{255, 255, 255, 0} |
| 433 | v4mappedv6mask = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 255, 255, 255, 0} |
| 434 | v6mask = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0} |
| 435 | badaddr = IP{192, 168, 0} |
| 436 | badmask = IPMask{255, 255, 0} |
| 437 | v4maskzero = IPMask{0, 0, 0, 0} |
| 438 | ) |
| 439 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 440 | var networkNumberAndMaskTests = []struct { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 441 | in IPNet |
| 442 | out IPNet |
| 443 | }{ |
Mikio Hara | e8cf49f | 2012-11-27 00:45:42 +0900 | [diff] [blame] | 444 | {IPNet{IP: v4addr, Mask: v4mask}, IPNet{IP: v4addr, Mask: v4mask}}, |
| 445 | {IPNet{IP: v4addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}}, |
| 446 | {IPNet{IP: v4mappedv6addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}}, |
| 447 | {IPNet{IP: v4mappedv6addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}}, |
| 448 | {IPNet{IP: v4addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}}, |
| 449 | {IPNet{IP: v6addr, Mask: v6mask}, IPNet{IP: v6addr, Mask: v6mask}}, |
| 450 | {IPNet{IP: v6addr, Mask: v4mappedv6mask}, IPNet{IP: v6addr, Mask: v4mappedv6mask}}, |
| 451 | {in: IPNet{IP: v6addr, Mask: v4mask}}, |
| 452 | {in: IPNet{IP: v4addr, Mask: badmask}}, |
| 453 | {in: IPNet{IP: v4mappedv6addr, Mask: badmask}}, |
| 454 | {in: IPNet{IP: v6addr, Mask: badmask}}, |
| 455 | {in: IPNet{IP: badaddr, Mask: v4mask}}, |
| 456 | {in: IPNet{IP: badaddr, Mask: v4mappedv6mask}}, |
| 457 | {in: IPNet{IP: badaddr, Mask: v6mask}}, |
| 458 | {in: IPNet{IP: badaddr, Mask: badmask}}, |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 459 | } |
| 460 | |
| 461 | func TestNetworkNumberAndMask(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 462 | for _, tt := range networkNumberAndMaskTests { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 463 | ip, m := networkNumberAndMask(&tt.in) |
Mikio Hara | e8cf49f | 2012-11-27 00:45:42 +0900 | [diff] [blame] | 464 | out := &IPNet{IP: ip, Mask: m} |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 465 | if !reflect.DeepEqual(&tt.out, out) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 466 | t.Errorf("networkNumberAndMask(%v) = %v, want %v", tt.in, out, &tt.out) |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 467 | } |
| 468 | } |
| 469 | } |
| 470 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 471 | var splitJoinTests = []struct { |
| 472 | host string |
| 473 | port string |
| 474 | join string |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 475 | }{ |
| 476 | {"www.google.com", "80", "www.google.com:80"}, |
| 477 | {"127.0.0.1", "1234", "127.0.0.1:1234"}, |
| 478 | {"::1", "80", "[::1]:80"}, |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 479 | {"fe80::1%lo0", "80", "[fe80::1%lo0]:80"}, |
| 480 | {"localhost%lo0", "80", "[localhost%lo0]:80"}, |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 481 | {"", "0", ":0"}, |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 482 | |
| 483 | {"google.com", "https%foo", "google.com:https%foo"}, // Go 1.0 behavior |
Martin Möhrmann | fdd0179 | 2016-02-24 11:55:20 +0100 | [diff] [blame] | 484 | {"127.0.0.1", "", "127.0.0.1:"}, // Go 1.0 behavior |
| 485 | {"www.google.com", "", "www.google.com:"}, // Go 1.0 behavior |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 486 | } |
| 487 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 488 | var splitFailureTests = []struct { |
| 489 | hostPort string |
| 490 | err string |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 491 | }{ |
| 492 | {"www.google.com", "missing port in address"}, |
| 493 | {"127.0.0.1", "missing port in address"}, |
| 494 | {"[::1]", "missing port in address"}, |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 495 | {"[fe80::1%lo0]", "missing port in address"}, |
| 496 | {"[localhost%lo0]", "missing port in address"}, |
| 497 | {"localhost%lo0", "missing port in address"}, |
| 498 | |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 499 | {"::1", "too many colons in address"}, |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 500 | {"fe80::1%lo0", "too many colons in address"}, |
| 501 | {"fe80::1%lo0:80", "too many colons in address"}, |
| 502 | |
| 503 | {"localhost%lo0:80", "missing brackets in address"}, |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 504 | |
| 505 | // Test cases that didn't fail in Go 1.0 |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 506 | |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 507 | {"[foo:bar]", "missing port in address"}, |
| 508 | {"[foo:bar]baz", "missing port in address"}, |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 509 | {"[foo]bar:baz", "missing port in address"}, |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 510 | |
| 511 | {"[foo]:[bar]:baz", "too many colons in address"}, |
| 512 | |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 513 | {"[foo]:[bar]baz", "unexpected '[' in address"}, |
| 514 | {"foo[bar]:baz", "unexpected '[' in address"}, |
Mikio Hara | aa0dda7 | 2013-03-23 09:57:40 +0900 | [diff] [blame] | 515 | |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 516 | {"foo]bar:baz", "unexpected ']' in address"}, |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 517 | } |
| 518 | |
| 519 | func TestSplitHostPort(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 520 | for _, tt := range splitJoinTests { |
| 521 | if host, port, err := SplitHostPort(tt.join); host != tt.host || port != tt.port || err != nil { |
| 522 | t.Errorf("SplitHostPort(%q) = %q, %q, %v; want %q, %q, nil", tt.join, host, port, err, tt.host, tt.port) |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 523 | } |
| 524 | } |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 525 | for _, tt := range splitFailureTests { |
Dave Day | 5630cb7 | 2016-03-16 10:24:03 +1100 | [diff] [blame] | 526 | if host, port, err := SplitHostPort(tt.hostPort); err == nil { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 527 | t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort) |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 528 | } else { |
| 529 | e := err.(*AddrError) |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 530 | if e.Err != tt.err { |
| 531 | t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err) |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 532 | } |
Dave Day | 5630cb7 | 2016-03-16 10:24:03 +1100 | [diff] [blame] | 533 | if host != "" || port != "" { |
| 534 | t.Errorf("SplitHostPort(%q) = %q, %q, err; want %q, %q, err on failure", tt.hostPort, host, port, "", "") |
| 535 | } |
Michael Teichgräber | ad34184 | 2013-01-30 09:25:16 -0800 | [diff] [blame] | 536 | } |
| 537 | } |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 538 | } |
| 539 | |
| 540 | func TestJoinHostPort(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 541 | for _, tt := range splitJoinTests { |
| 542 | if join := JoinHostPort(tt.host, tt.port); join != tt.join { |
| 543 | t.Errorf("JoinHostPort(%q, %q) = %q; want %q", tt.host, tt.port, join, tt.join) |
Russ Cox | 41f93a4 | 2011-03-28 23:28:42 -0400 | [diff] [blame] | 544 | } |
| 545 | } |
| 546 | } |
Mikio Hara | 2ddcad9 | 2011-05-16 17:03:06 -0400 | [diff] [blame] | 547 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 548 | var ipAddrFamilyTests = []struct { |
Mikio Hara | 2ddcad9 | 2011-05-16 17:03:06 -0400 | [diff] [blame] | 549 | in IP |
| 550 | af4 bool |
| 551 | af6 bool |
| 552 | }{ |
| 553 | {IPv4bcast, true, false}, |
| 554 | {IPv4allsys, true, false}, |
| 555 | {IPv4allrouter, true, false}, |
| 556 | {IPv4zero, true, false}, |
| 557 | {IPv4(224, 0, 0, 1), true, false}, |
| 558 | {IPv4(127, 0, 0, 1), true, false}, |
| 559 | {IPv4(240, 0, 0, 1), true, false}, |
| 560 | {IPv6unspecified, false, true}, |
| 561 | {IPv6loopback, false, true}, |
| 562 | {IPv6interfacelocalallnodes, false, true}, |
| 563 | {IPv6linklocalallnodes, false, true}, |
| 564 | {IPv6linklocalallrouters, false, true}, |
| 565 | {ParseIP("ff05::a:b:c:d"), false, true}, |
| 566 | {ParseIP("fe80::1:2:3:4"), false, true}, |
| 567 | {ParseIP("2001:db8::123:12:1"), false, true}, |
| 568 | } |
| 569 | |
| 570 | func TestIPAddrFamily(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 571 | for _, tt := range ipAddrFamilyTests { |
Mikio Hara | 2ddcad9 | 2011-05-16 17:03:06 -0400 | [diff] [blame] | 572 | if af := tt.in.To4() != nil; af != tt.af4 { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 573 | t.Errorf("verifying IPv4 address family for %q = %v, want %v", tt.in, af, tt.af4) |
Mikio Hara | 2ddcad9 | 2011-05-16 17:03:06 -0400 | [diff] [blame] | 574 | } |
| 575 | if af := len(tt.in) == IPv6len && tt.in.To4() == nil; af != tt.af6 { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 576 | t.Errorf("verifying IPv6 address family for %q = %v, want %v", tt.in, af, tt.af6) |
Mikio Hara | 2ddcad9 | 2011-05-16 17:03:06 -0400 | [diff] [blame] | 577 | } |
| 578 | } |
| 579 | } |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 580 | |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 581 | var ipAddrScopeTests = []struct { |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 582 | scope func(IP) bool |
| 583 | in IP |
| 584 | ok bool |
| 585 | }{ |
| 586 | {IP.IsUnspecified, IPv4zero, true}, |
| 587 | {IP.IsUnspecified, IPv4(127, 0, 0, 1), false}, |
| 588 | {IP.IsUnspecified, IPv6unspecified, true}, |
| 589 | {IP.IsUnspecified, IPv6interfacelocalallnodes, false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 590 | {IP.IsUnspecified, nil, false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 591 | {IP.IsLoopback, IPv4(127, 0, 0, 1), true}, |
| 592 | {IP.IsLoopback, IPv4(127, 255, 255, 254), true}, |
| 593 | {IP.IsLoopback, IPv4(128, 1, 2, 3), false}, |
| 594 | {IP.IsLoopback, IPv6loopback, true}, |
| 595 | {IP.IsLoopback, IPv6linklocalallrouters, false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 596 | {IP.IsLoopback, nil, false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 597 | {IP.IsMulticast, IPv4(224, 0, 0, 0), true}, |
| 598 | {IP.IsMulticast, IPv4(239, 0, 0, 0), true}, |
| 599 | {IP.IsMulticast, IPv4(240, 0, 0, 0), false}, |
| 600 | {IP.IsMulticast, IPv6linklocalallnodes, true}, |
| 601 | {IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true}, |
| 602 | {IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 603 | {IP.IsMulticast, nil, false}, |
| 604 | {IP.IsInterfaceLocalMulticast, IPv4(224, 0, 0, 0), false}, |
| 605 | {IP.IsInterfaceLocalMulticast, IPv4(0xff, 0x01, 0, 0), false}, |
| 606 | {IP.IsInterfaceLocalMulticast, IPv6interfacelocalallnodes, true}, |
| 607 | {IP.IsInterfaceLocalMulticast, nil, false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 608 | {IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true}, |
| 609 | {IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 610 | {IP.IsLinkLocalMulticast, IPv4(0xff, 0x02, 0, 0), false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 611 | {IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true}, |
| 612 | {IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 613 | {IP.IsLinkLocalMulticast, nil, false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 614 | {IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true}, |
| 615 | {IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 616 | {IP.IsLinkLocalUnicast, IPv4(0xfe, 0x80, 0, 0), false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 617 | {IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true}, |
| 618 | {IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 619 | {IP.IsLinkLocalUnicast, nil, false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 620 | {IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true}, |
| 621 | {IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false}, |
| 622 | {IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 623 | {IP.IsGlobalUnicast, IPv4bcast, false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 624 | {IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true}, |
| 625 | {IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false}, |
| 626 | {IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false}, |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 627 | {IP.IsGlobalUnicast, nil, false}, |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 628 | } |
| 629 | |
| 630 | func name(f interface{}) string { |
| 631 | return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name() |
| 632 | } |
| 633 | |
| 634 | func TestIPAddrScope(t *testing.T) { |
Mikio Hara | 3560f3b | 2013-03-20 01:07:18 +0900 | [diff] [blame] | 635 | for _, tt := range ipAddrScopeTests { |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 636 | if ok := tt.scope(tt.in); ok != tt.ok { |
Mikio Hara | a2c2c87 | 2011-09-07 14:01:12 -0400 | [diff] [blame] | 637 | t.Errorf("%s(%q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok) |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 638 | } |
Mikio Hara | 91ba0ab | 2015-07-04 13:49:47 +0900 | [diff] [blame] | 639 | ip := tt.in.To4() |
| 640 | if ip == nil { |
| 641 | continue |
| 642 | } |
| 643 | if ok := tt.scope(ip); ok != tt.ok { |
| 644 | t.Errorf("%s(%q) = %v, want %v", name(tt.scope), ip, ok, tt.ok) |
| 645 | } |
Mikio Hara | db36e03 | 2011-05-16 23:21:13 -0400 | [diff] [blame] | 646 | } |
| 647 | } |