ip_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  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. package net
  5. import (
  6. "reflect"
  7. "runtime"
  8. "testing"
  9. )
  10. var parseIPTests = []struct {
  11. in string
  12. out IP
  13. }{
  14. {"127.0.1.2", IPv4(127, 0, 1, 2)},
  15. {"127.0.0.1", IPv4(127, 0, 0, 1)},
  16. {"127.0.0.256", nil},
  17. {"abc", nil},
  18. {"123:", nil},
  19. {"::ffff:127.0.0.1", IPv4(127, 0, 0, 1)},
  20. {"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
  21. {"::ffff:4a7d:1363", IPv4(74, 125, 19, 99)},
  22. {"fe80::1%lo0", nil},
  23. {"fe80::1%911", nil},
  24. {"", nil},
  25. {"a1:a2:a3:a4::b1:b2:b3:b4", nil}, // Issue 6628
  26. }
  27. func TestParseIP(t *testing.T) {
  28. for _, tt := range parseIPTests {
  29. if out := ParseIP(tt.in); !reflect.DeepEqual(out, tt.out) {
  30. t.Errorf("ParseIP(%q) = %v, want %v", tt.in, out, tt.out)
  31. }
  32. if tt.in == "" {
  33. // Tested in TestMarshalEmptyIP below.
  34. continue
  35. }
  36. var out IP
  37. if err := out.UnmarshalText([]byte(tt.in)); !reflect.DeepEqual(out, tt.out) || (tt.out == nil) != (err != nil) {
  38. t.Errorf("IP.UnmarshalText(%q) = %v, %v, want %v", tt.in, out, err, tt.out)
  39. }
  40. }
  41. }
  42. func BenchmarkParseIP(b *testing.B) {
  43. for i := 0; i < b.N; i++ {
  44. for _, tt := range parseIPTests {
  45. ParseIP(tt.in)
  46. }
  47. }
  48. }
  49. // Issue 6339
  50. func TestMarshalEmptyIP(t *testing.T) {
  51. for _, in := range [][]byte{nil, []byte("")} {
  52. var out = IP{1, 2, 3, 4}
  53. if err := out.UnmarshalText(in); err != nil || out != nil {
  54. t.Errorf("UnmarshalText(%v) = %v, %v; want nil, nil", in, out, err)
  55. }
  56. }
  57. var ip IP
  58. got, err := ip.MarshalText()
  59. if err != nil {
  60. t.Fatal(err)
  61. }
  62. if !reflect.DeepEqual(got, []byte("")) {
  63. t.Errorf(`got %#v, want []byte("")`, got)
  64. }
  65. }
  66. var ipStringTests = []struct {
  67. in IP
  68. out string // see RFC 5952
  69. }{
  70. {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, "2001:db8::123:12:1"},
  71. {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1}, "2001:db8::1"},
  72. {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1}, "2001:db8:0:1:0:1:0:1"},
  73. {IP{0x20, 0x1, 0xd, 0xb8, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0}, "2001:db8:1:0:1:0:1:0"},
  74. {IP{0x20, 0x1, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, "2001::1:0:0:1"},
  75. {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0}, "2001:db8:0:0:1::"},
  76. {IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, "2001:db8::1:0:0:1"},
  77. {IP{0x20, 0x1, 0xD, 0xB8, 0, 0, 0, 0, 0, 0xA, 0, 0xB, 0, 0xC, 0, 0xD}, "2001:db8::a:b:c:d"},
  78. {IPv4(192, 168, 0, 1), "192.168.0.1"},
  79. {nil, ""},
  80. }
  81. func TestIPString(t *testing.T) {
  82. for _, tt := range ipStringTests {
  83. if tt.in != nil {
  84. if out := tt.in.String(); out != tt.out {
  85. t.Errorf("IP.String(%v) = %q, want %q", tt.in, out, tt.out)
  86. }
  87. }
  88. if out, err := tt.in.MarshalText(); string(out) != tt.out || err != nil {
  89. t.Errorf("IP.MarshalText(%v) = %q, %v, want %q, nil", tt.in, out, err, tt.out)
  90. }
  91. }
  92. }
  93. func BenchmarkIPString(b *testing.B) {
  94. for i := 0; i < b.N; i++ {
  95. for _, tt := range ipStringTests {
  96. if tt.in != nil {
  97. tt.in.String()
  98. }
  99. }
  100. }
  101. }
  102. var ipMaskTests = []struct {
  103. in IP
  104. mask IPMask
  105. out IP
  106. }{
  107. {IPv4(192, 168, 1, 127), IPv4Mask(255, 255, 255, 128), IPv4(192, 168, 1, 0)},
  108. {IPv4(192, 168, 1, 127), IPMask(ParseIP("255.255.255.192")), IPv4(192, 168, 1, 64)},
  109. {IPv4(192, 168, 1, 127), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0")), IPv4(192, 168, 1, 96)},
  110. {IPv4(192, 168, 1, 127), IPv4Mask(255, 0, 255, 0), IPv4(192, 0, 1, 0)},
  111. {ParseIP("2001:db8::1"), IPMask(ParseIP("ffff:ff80::")), ParseIP("2001:d80::")},
  112. {ParseIP("2001:db8::1"), IPMask(ParseIP("f0f0:0f0f::")), ParseIP("2000:d08::")},
  113. }
  114. func TestIPMask(t *testing.T) {
  115. for _, tt := range ipMaskTests {
  116. if out := tt.in.Mask(tt.mask); out == nil || !tt.out.Equal(out) {
  117. t.Errorf("IP(%v).Mask(%v) = %v, want %v", tt.in, tt.mask, out, tt.out)
  118. }
  119. }
  120. }
  121. var ipMaskStringTests = []struct {
  122. in IPMask
  123. out string
  124. }{
  125. {IPv4Mask(255, 255, 255, 240), "fffffff0"},
  126. {IPv4Mask(255, 0, 128, 0), "ff008000"},
  127. {IPMask(ParseIP("ffff:ff80::")), "ffffff80000000000000000000000000"},
  128. {IPMask(ParseIP("ef00:ff80::cafe:0")), "ef00ff800000000000000000cafe0000"},
  129. {nil, "<nil>"},
  130. }
  131. func TestIPMaskString(t *testing.T) {
  132. for _, tt := range ipMaskStringTests {
  133. if out := tt.in.String(); out != tt.out {
  134. t.Errorf("IPMask.String(%v) = %q, want %q", tt.in, out, tt.out)
  135. }
  136. }
  137. }
  138. func BenchmarkIPMaskString(b *testing.B) {
  139. for i := 0; i < b.N; i++ {
  140. for _, tt := range ipMaskStringTests {
  141. tt.in.String()
  142. }
  143. }
  144. }
  145. var parseCIDRTests = []struct {
  146. in string
  147. ip IP
  148. net *IPNet
  149. err error
  150. }{
  151. {"135.104.0.0/32", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 255)}, nil},
  152. {"0.0.0.0/24", IPv4(0, 0, 0, 0), &IPNet{IP: IPv4(0, 0, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
  153. {"135.104.0.0/24", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
  154. {"135.104.0.1/32", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 1), Mask: IPv4Mask(255, 255, 255, 255)}, nil},
  155. {"135.104.0.1/24", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
  156. {"::1/128", ParseIP("::1"), &IPNet{IP: ParseIP("::1"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))}, nil},
  157. {"abcd:2345::/127", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"))}, nil},
  158. {"abcd:2345::/65", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:8000::"))}, nil},
  159. {"abcd:2345::/64", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff::"))}, nil},
  160. {"abcd:2345::/63", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:fffe::"))}, nil},
  161. {"abcd:2345::/33", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:8000::"))}, nil},
  162. {"abcd:2345::/32", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff::"))}, nil},
  163. {"abcd:2344::/31", ParseIP("abcd:2344::"), &IPNet{IP: ParseIP("abcd:2344::"), Mask: IPMask(ParseIP("ffff:fffe::"))}, nil},
  164. {"abcd:2300::/24", ParseIP("abcd:2300::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
  165. {"abcd:2345::/24", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
  166. {"2001:DB8::/48", ParseIP("2001:DB8::"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
  167. {"2001:DB8::1/48", ParseIP("2001:DB8::1"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
  168. {"192.168.1.1/255.255.255.0", nil, nil, &ParseError{"CIDR address", "192.168.1.1/255.255.255.0"}},
  169. {"192.168.1.1/35", nil, nil, &ParseError{"CIDR address", "192.168.1.1/35"}},
  170. {"2001:db8::1/-1", nil, nil, &ParseError{"CIDR address", "2001:db8::1/-1"}},
  171. {"", nil, nil, &ParseError{"CIDR address", ""}},
  172. }
  173. func TestParseCIDR(t *testing.T) {
  174. for _, tt := range parseCIDRTests {
  175. ip, net, err := ParseCIDR(tt.in)
  176. if !reflect.DeepEqual(err, tt.err) {
  177. t.Errorf("ParseCIDR(%q) = %v, %v; want %v, %v", tt.in, ip, net, tt.ip, tt.net)
  178. }
  179. if err == nil && (!tt.ip.Equal(ip) || !tt.net.IP.Equal(net.IP) || !reflect.DeepEqual(net.Mask, tt.net.Mask)) {
  180. 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)
  181. }
  182. }
  183. }
  184. var ipNetContainsTests = []struct {
  185. ip IP
  186. net *IPNet
  187. ok bool
  188. }{
  189. {IPv4(172, 16, 1, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(12, 32)}, true},
  190. {IPv4(172, 24, 0, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(13, 32)}, false},
  191. {IPv4(192, 168, 0, 3), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 0, 255, 252)}, true},
  192. {IPv4(192, 168, 0, 4), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 255, 0, 252)}, false},
  193. {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: CIDRMask(47, 128)}, true},
  194. {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:2::"), Mask: CIDRMask(47, 128)}, false},
  195. {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("ffff:0:ffff::"))}, true},
  196. {ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("0:0:0:ffff::"))}, false},
  197. }
  198. func TestIPNetContains(t *testing.T) {
  199. for _, tt := range ipNetContainsTests {
  200. if ok := tt.net.Contains(tt.ip); ok != tt.ok {
  201. t.Errorf("IPNet(%v).Contains(%v) = %v, want %v", tt.net, tt.ip, ok, tt.ok)
  202. }
  203. }
  204. }
  205. var ipNetStringTests = []struct {
  206. in *IPNet
  207. out string
  208. }{
  209. {&IPNet{IP: IPv4(192, 168, 1, 0), Mask: CIDRMask(26, 32)}, "192.168.1.0/26"},
  210. {&IPNet{IP: IPv4(192, 168, 1, 0), Mask: IPv4Mask(255, 0, 255, 0)}, "192.168.1.0/ff00ff00"},
  211. {&IPNet{IP: ParseIP("2001:db8::"), Mask: CIDRMask(55, 128)}, "2001:db8::/55"},
  212. {&IPNet{IP: ParseIP("2001:db8::"), Mask: IPMask(ParseIP("8000:f123:0:cafe::"))}, "2001:db8::/8000f1230000cafe0000000000000000"},
  213. }
  214. func TestIPNetString(t *testing.T) {
  215. for _, tt := range ipNetStringTests {
  216. if out := tt.in.String(); out != tt.out {
  217. t.Errorf("IPNet.String(%v) = %q, want %q", tt.in, out, tt.out)
  218. }
  219. }
  220. }
  221. var cidrMaskTests = []struct {
  222. ones int
  223. bits int
  224. out IPMask
  225. }{
  226. {0, 32, IPv4Mask(0, 0, 0, 0)},
  227. {12, 32, IPv4Mask(255, 240, 0, 0)},
  228. {24, 32, IPv4Mask(255, 255, 255, 0)},
  229. {32, 32, IPv4Mask(255, 255, 255, 255)},
  230. {0, 128, IPMask{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  231. {4, 128, IPMask{0xf0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  232. {48, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
  233. {128, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
  234. {33, 32, nil},
  235. {32, 33, nil},
  236. {-1, 128, nil},
  237. {128, -1, nil},
  238. }
  239. func TestCIDRMask(t *testing.T) {
  240. for _, tt := range cidrMaskTests {
  241. if out := CIDRMask(tt.ones, tt.bits); !reflect.DeepEqual(out, tt.out) {
  242. t.Errorf("CIDRMask(%v, %v) = %v, want %v", tt.ones, tt.bits, out, tt.out)
  243. }
  244. }
  245. }
  246. var (
  247. v4addr = IP{192, 168, 0, 1}
  248. v4mappedv6addr = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 0, 1}
  249. v6addr = IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}
  250. v4mask = IPMask{255, 255, 255, 0}
  251. v4mappedv6mask = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 255, 255, 255, 0}
  252. v6mask = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}
  253. badaddr = IP{192, 168, 0}
  254. badmask = IPMask{255, 255, 0}
  255. v4maskzero = IPMask{0, 0, 0, 0}
  256. )
  257. var networkNumberAndMaskTests = []struct {
  258. in IPNet
  259. out IPNet
  260. }{
  261. {IPNet{IP: v4addr, Mask: v4mask}, IPNet{IP: v4addr, Mask: v4mask}},
  262. {IPNet{IP: v4addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}},
  263. {IPNet{IP: v4mappedv6addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}},
  264. {IPNet{IP: v4mappedv6addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}},
  265. {IPNet{IP: v4addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}},
  266. {IPNet{IP: v6addr, Mask: v6mask}, IPNet{IP: v6addr, Mask: v6mask}},
  267. {IPNet{IP: v6addr, Mask: v4mappedv6mask}, IPNet{IP: v6addr, Mask: v4mappedv6mask}},
  268. {in: IPNet{IP: v6addr, Mask: v4mask}},
  269. {in: IPNet{IP: v4addr, Mask: badmask}},
  270. {in: IPNet{IP: v4mappedv6addr, Mask: badmask}},
  271. {in: IPNet{IP: v6addr, Mask: badmask}},
  272. {in: IPNet{IP: badaddr, Mask: v4mask}},
  273. {in: IPNet{IP: badaddr, Mask: v4mappedv6mask}},
  274. {in: IPNet{IP: badaddr, Mask: v6mask}},
  275. {in: IPNet{IP: badaddr, Mask: badmask}},
  276. }
  277. func TestNetworkNumberAndMask(t *testing.T) {
  278. for _, tt := range networkNumberAndMaskTests {
  279. ip, m := networkNumberAndMask(&tt.in)
  280. out := &IPNet{IP: ip, Mask: m}
  281. if !reflect.DeepEqual(&tt.out, out) {
  282. t.Errorf("networkNumberAndMask(%v) = %v, want %v", tt.in, out, &tt.out)
  283. }
  284. }
  285. }
  286. var splitJoinTests = []struct {
  287. host string
  288. port string
  289. join string
  290. }{
  291. {"www.google.com", "80", "www.google.com:80"},
  292. {"127.0.0.1", "1234", "127.0.0.1:1234"},
  293. {"::1", "80", "[::1]:80"},
  294. {"fe80::1%lo0", "80", "[fe80::1%lo0]:80"},
  295. {"localhost%lo0", "80", "[localhost%lo0]:80"},
  296. {"", "0", ":0"},
  297. {"google.com", "https%foo", "google.com:https%foo"}, // Go 1.0 behavior
  298. {"127.0.0.1", "", "127.0.0.1:"}, // Go 1.0 behaviour
  299. {"www.google.com", "", "www.google.com:"}, // Go 1.0 behaviour
  300. }
  301. var splitFailureTests = []struct {
  302. hostPort string
  303. err string
  304. }{
  305. {"www.google.com", "missing port in address"},
  306. {"127.0.0.1", "missing port in address"},
  307. {"[::1]", "missing port in address"},
  308. {"[fe80::1%lo0]", "missing port in address"},
  309. {"[localhost%lo0]", "missing port in address"},
  310. {"localhost%lo0", "missing port in address"},
  311. {"::1", "too many colons in address"},
  312. {"fe80::1%lo0", "too many colons in address"},
  313. {"fe80::1%lo0:80", "too many colons in address"},
  314. {"localhost%lo0:80", "missing brackets in address"},
  315. // Test cases that didn't fail in Go 1.0
  316. {"[foo:bar]", "missing port in address"},
  317. {"[foo:bar]baz", "missing port in address"},
  318. {"[foo]bar:baz", "missing port in address"},
  319. {"[foo]:[bar]:baz", "too many colons in address"},
  320. {"[foo]:[bar]baz", "unexpected '[' in address"},
  321. {"foo[bar]:baz", "unexpected '[' in address"},
  322. {"foo]bar:baz", "unexpected ']' in address"},
  323. }
  324. func TestSplitHostPort(t *testing.T) {
  325. for _, tt := range splitJoinTests {
  326. if host, port, err := SplitHostPort(tt.join); host != tt.host || port != tt.port || err != nil {
  327. t.Errorf("SplitHostPort(%q) = %q, %q, %v; want %q, %q, nil", tt.join, host, port, err, tt.host, tt.port)
  328. }
  329. }
  330. for _, tt := range splitFailureTests {
  331. if _, _, err := SplitHostPort(tt.hostPort); err == nil {
  332. t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort)
  333. } else {
  334. e := err.(*AddrError)
  335. if e.Err != tt.err {
  336. t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err)
  337. }
  338. }
  339. }
  340. }
  341. func TestJoinHostPort(t *testing.T) {
  342. for _, tt := range splitJoinTests {
  343. if join := JoinHostPort(tt.host, tt.port); join != tt.join {
  344. t.Errorf("JoinHostPort(%q, %q) = %q; want %q", tt.host, tt.port, join, tt.join)
  345. }
  346. }
  347. }
  348. var ipAddrFamilyTests = []struct {
  349. in IP
  350. af4 bool
  351. af6 bool
  352. }{
  353. {IPv4bcast, true, false},
  354. {IPv4allsys, true, false},
  355. {IPv4allrouter, true, false},
  356. {IPv4zero, true, false},
  357. {IPv4(224, 0, 0, 1), true, false},
  358. {IPv4(127, 0, 0, 1), true, false},
  359. {IPv4(240, 0, 0, 1), true, false},
  360. {IPv6unspecified, false, true},
  361. {IPv6loopback, false, true},
  362. {IPv6interfacelocalallnodes, false, true},
  363. {IPv6linklocalallnodes, false, true},
  364. {IPv6linklocalallrouters, false, true},
  365. {ParseIP("ff05::a:b:c:d"), false, true},
  366. {ParseIP("fe80::1:2:3:4"), false, true},
  367. {ParseIP("2001:db8::123:12:1"), false, true},
  368. }
  369. func TestIPAddrFamily(t *testing.T) {
  370. for _, tt := range ipAddrFamilyTests {
  371. if af := tt.in.To4() != nil; af != tt.af4 {
  372. t.Errorf("verifying IPv4 address family for %q = %v, want %v", tt.in, af, tt.af4)
  373. }
  374. if af := len(tt.in) == IPv6len && tt.in.To4() == nil; af != tt.af6 {
  375. t.Errorf("verifying IPv6 address family for %q = %v, want %v", tt.in, af, tt.af6)
  376. }
  377. }
  378. }
  379. var ipAddrScopeTests = []struct {
  380. scope func(IP) bool
  381. in IP
  382. ok bool
  383. }{
  384. {IP.IsUnspecified, IPv4zero, true},
  385. {IP.IsUnspecified, IPv4(127, 0, 0, 1), false},
  386. {IP.IsUnspecified, IPv6unspecified, true},
  387. {IP.IsUnspecified, IPv6interfacelocalallnodes, false},
  388. {IP.IsLoopback, IPv4(127, 0, 0, 1), true},
  389. {IP.IsLoopback, IPv4(127, 255, 255, 254), true},
  390. {IP.IsLoopback, IPv4(128, 1, 2, 3), false},
  391. {IP.IsLoopback, IPv6loopback, true},
  392. {IP.IsLoopback, IPv6linklocalallrouters, false},
  393. {IP.IsMulticast, IPv4(224, 0, 0, 0), true},
  394. {IP.IsMulticast, IPv4(239, 0, 0, 0), true},
  395. {IP.IsMulticast, IPv4(240, 0, 0, 0), false},
  396. {IP.IsMulticast, IPv6linklocalallnodes, true},
  397. {IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
  398. {IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
  399. {IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true},
  400. {IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false},
  401. {IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true},
  402. {IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
  403. {IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true},
  404. {IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false},
  405. {IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
  406. {IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
  407. {IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true},
  408. {IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false},
  409. {IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false},
  410. {IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true},
  411. {IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
  412. {IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
  413. }
  414. func name(f interface{}) string {
  415. return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
  416. }
  417. func TestIPAddrScope(t *testing.T) {
  418. for _, tt := range ipAddrScopeTests {
  419. if ok := tt.scope(tt.in); ok != tt.ok {
  420. t.Errorf("%s(%q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok)
  421. }
  422. }
  423. }