1package sockaddr_test 2 3import ( 4 "fmt" 5 "math/big" 6 "strings" 7 "testing" 8 9 sockaddr "github.com/hashicorp/go-sockaddr" 10) 11 12// ipv6HostMask is an unexported big.Int representing a /128 IPv6 address 13var ipv6HostMask sockaddr.IPv6Mask 14 15func init() { 16 biMask := big.NewInt(0) 17 biMask = biMask.SetBytes([]byte{ 18 0xff, 0xff, 19 0xff, 0xff, 20 0xff, 0xff, 21 0xff, 0xff, 22 0xff, 0xff, 23 0xff, 0xff, 24 0xff, 0xff, 25 0xff, 0xff, 26 }, 27 ) 28 ipv6HostMask = sockaddr.IPv6Mask(biMask) 29} 30 31func newIPv6BigInt(t *testing.T, ipv6Str string) *big.Int { 32 addr := big.NewInt(0) 33 addrStr := strings.Join(strings.Split(ipv6Str, ":"), "") 34 _, ok := addr.SetString(addrStr, 16) 35 if !ok { 36 t.Fatalf("Unable to create an IPv6Addr from string %+q", ipv6Str) 37 } 38 39 return addr 40} 41 42func newIPv6Address(t *testing.T, ipv6Str string) sockaddr.IPv6Address { 43 return sockaddr.IPv6Address(newIPv6BigInt(t, ipv6Str)) 44} 45 46func newIPv6Mask(t *testing.T, ipv6Str string) sockaddr.IPv6Mask { 47 return sockaddr.IPv6Mask(newIPv6BigInt(t, ipv6Str)) 48} 49 50func newIPv6Network(t *testing.T, ipv6Str string) sockaddr.IPv6Network { 51 return sockaddr.IPv6Network(newIPv6BigInt(t, ipv6Str)) 52} 53 54func TestSockAddr_IPv6Addr(t *testing.T) { 55 tests := []struct { 56 z00_input string 57 z01_addrHexStr string 58 z02_addrBinStr string 59 z03_addrStr string 60 z04_NetIPStringOut string 61 z05_addrInt sockaddr.IPv6Address 62 z06_netInt sockaddr.IPv6Network 63 z07_ipMaskStr string 64 z08_maskbits int 65 z09_NetIPNetStringOut string 66 z10_maskInt sockaddr.IPv6Mask 67 z11_networkStr string 68 z12_octets []int 69 z13_firstUsable string 70 z14_lastUsable string 71 z16_portInt sockaddr.IPPort 72 z17_DialPacketArgs []string 73 z18_DialStreamArgs []string 74 z19_ListenPacketArgs []string 75 z20_ListenStreamArgs []string 76 z99_pass bool 77 }{ 78 { // 0 -- IPv4 fail 79 z00_input: "1.2.3.4", 80 z99_pass: false, 81 }, 82 { // 1 - IPv4 with port 83 z00_input: "5.6.7.8:80", 84 z99_pass: false, 85 }, 86 { // 2 - Hostname 87 z00_input: "www.hashicorp.com", 88 z99_pass: false, 89 }, 90 { // 3 - IPv6 with port, but no square brackets 91 z00_input: "2607:f0d0:1002:0051:0000:0000:0000:0004:8600", 92 z99_pass: false, 93 }, 94 { // 4 - IPv6 with port 95 z00_input: "[2607:f0d0:1002:0051:0000:0000:0000:0004]:8600", 96 z01_addrHexStr: "2607f0d0100200510000000000000004", 97 z02_addrBinStr: "00100110000001111111000011010000000100000000001000000000010100010000000000000000000000000000000000000000000000000000000000000100", 98 z03_addrStr: "[2607:f0d0:1002:51::4]:8600", 99 z04_NetIPStringOut: "2607:f0d0:1002:51::4", 100 z05_addrInt: newIPv6Address(t, "2607:f0d0:1002:0051:0000:0000:0000:0004"), 101 z06_netInt: newIPv6Network(t, "2607:f0d0:1002:0051:0000:0000:0000:0004"), 102 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 103 z08_maskbits: 128, 104 z09_NetIPNetStringOut: "2607:f0d0:1002:51::4/128", 105 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 106 z11_networkStr: "2607:f0d0:1002:51::4", 107 z12_octets: []int{0x26, 0x7, 0xf0, 0xd0, 0x10, 0x2, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4}, 108 z13_firstUsable: "2607:f0d0:1002:51::4", 109 z14_lastUsable: "2607:f0d0:1002:51::4", 110 z16_portInt: 8600, 111 z17_DialPacketArgs: []string{"udp6", "[2607:f0d0:1002:51::4]:8600"}, 112 z18_DialStreamArgs: []string{"tcp6", "[2607:f0d0:1002:51::4]:8600"}, 113 z19_ListenPacketArgs: []string{"udp6", "[2607:f0d0:1002:51::4]:8600"}, 114 z20_ListenStreamArgs: []string{"tcp6", "[2607:f0d0:1002:51::4]:8600"}, 115 z99_pass: true, 116 }, 117 { // 5 - IPv6 118 z00_input: "2607:f0d0:1002:0051:0000:0000:0000:0004", 119 z01_addrHexStr: "2607f0d0100200510000000000000004", 120 z02_addrBinStr: "00100110000001111111000011010000000100000000001000000000010100010000000000000000000000000000000000000000000000000000000000000100", 121 z03_addrStr: "2607:f0d0:1002:51::4", 122 z04_NetIPStringOut: "2607:f0d0:1002:51::4", 123 z05_addrInt: newIPv6Address(t, "2607:f0d0:1002:0051:0000:0000:0000:0004"), 124 z06_netInt: newIPv6Network(t, "2607:f0d0:1002:0051:0000:0000:0000:0004"), 125 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 126 z08_maskbits: 128, 127 z09_NetIPNetStringOut: "2607:f0d0:1002:51::4/128", 128 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 129 z11_networkStr: "2607:f0d0:1002:51::4", 130 z12_octets: []int{0x26, 0x7, 0xf0, 0xd0, 0x10, 0x2, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4}, 131 z13_firstUsable: "2607:f0d0:1002:51::4", 132 z14_lastUsable: "2607:f0d0:1002:51::4", 133 z17_DialPacketArgs: []string{"udp6", ""}, 134 z18_DialStreamArgs: []string{"tcp6", ""}, 135 z19_ListenPacketArgs: []string{"udp6", "[2607:f0d0:1002:51::4]:0"}, 136 z20_ListenStreamArgs: []string{"tcp6", "[2607:f0d0:1002:51::4]:0"}, 137 z99_pass: true, 138 }, 139 { // 6 IPv6 with square brackets, optional 140 z00_input: "[2607:f0d0:1002:0051:0000:0000:0000:0004]", 141 z01_addrHexStr: "2607f0d0100200510000000000000004", 142 z02_addrBinStr: "00100110000001111111000011010000000100000000001000000000010100010000000000000000000000000000000000000000000000000000000000000100", 143 z03_addrStr: "2607:f0d0:1002:51::4", 144 z04_NetIPStringOut: "2607:f0d0:1002:51::4", 145 z05_addrInt: newIPv6Address(t, "2607:f0d0:1002:0051:0000:0000:0000:0004"), 146 z06_netInt: newIPv6Network(t, "2607:f0d0:1002:0051:0000:0000:0000:0004"), 147 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 148 z08_maskbits: 128, 149 z09_NetIPNetStringOut: "2607:f0d0:1002:51::4/128", 150 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 151 z11_networkStr: "2607:f0d0:1002:51::4", 152 z12_octets: []int{0x26, 0x7, 0xf0, 0xd0, 0x10, 0x2, 0x0, 0x51, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4}, 153 z13_firstUsable: "2607:f0d0:1002:51::4", 154 z14_lastUsable: "2607:f0d0:1002:51::4", 155 z17_DialPacketArgs: []string{"udp6", ""}, 156 z18_DialStreamArgs: []string{"tcp6", ""}, 157 z19_ListenPacketArgs: []string{"udp6", "[2607:f0d0:1002:51::4]:0"}, 158 z20_ListenStreamArgs: []string{"tcp6", "[2607:f0d0:1002:51::4]:0"}, 159 z99_pass: true, 160 }, 161 { // 7 - unspecified address 162 z00_input: "0:0:0:0:0:0:0:0", 163 z01_addrHexStr: "00000000000000000000000000000000", 164 z02_addrBinStr: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 165 z03_addrStr: "::", 166 z04_NetIPStringOut: "::", 167 z05_addrInt: newIPv6Address(t, "0"), 168 z06_netInt: newIPv6Network(t, "0"), 169 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 170 z08_maskbits: 128, 171 z09_NetIPNetStringOut: "::/128", 172 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 173 z11_networkStr: "::", 174 z12_octets: []int{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 175 z13_firstUsable: "::", 176 z14_lastUsable: "::", 177 z17_DialPacketArgs: []string{"udp6", ""}, 178 z18_DialStreamArgs: []string{"tcp6", ""}, 179 z19_ListenPacketArgs: []string{"udp6", "[::]:0"}, 180 z20_ListenStreamArgs: []string{"tcp6", "[::]:0"}, 181 z99_pass: true, 182 }, 183 { // 8 - loopback address 184 z00_input: "0:0:0:0:0:0:0:1", 185 z01_addrHexStr: "00000000000000000000000000000001", 186 z02_addrBinStr: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 187 z03_addrStr: "::1", 188 z04_NetIPStringOut: "::1", 189 z05_addrInt: newIPv6Address(t, "0000:0000:0000:0000:0000:0000:0000:0001"), 190 z06_netInt: newIPv6Network(t, "0000:0000:0000:0000:0000:0000:0000:0001"), 191 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 192 z08_maskbits: 128, 193 z09_NetIPNetStringOut: "::1/128", 194 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 195 z11_networkStr: "::1", 196 z12_octets: []int{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01}, 197 z13_firstUsable: "::1", 198 z14_lastUsable: "::1", 199 z17_DialPacketArgs: []string{"udp6", ""}, 200 z18_DialStreamArgs: []string{"tcp6", ""}, 201 z19_ListenPacketArgs: []string{"udp6", "[::1]:0"}, 202 z20_ListenStreamArgs: []string{"tcp6", "[::1]:0"}, 203 z99_pass: true, 204 }, 205 { // 9 - IPv6 with CIDR (RFC 3849) 206 z00_input: "2001:DB8::/32", 207 z01_addrHexStr: "20010db8000000000000000000000000", 208 z02_addrBinStr: "00100000000000010000110110111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 209 z03_addrStr: "2001:db8::/32", 210 z04_NetIPStringOut: "2001:db8::", 211 z05_addrInt: newIPv6Address(t, "20010db8000000000000000000000000"), 212 z06_netInt: newIPv6Network(t, "20010db8000000000000000000000000"), 213 z07_ipMaskStr: "ffffffff000000000000000000000000", 214 z08_maskbits: 32, 215 z09_NetIPNetStringOut: "2001:db8::/32", 216 z10_maskInt: newIPv6Mask(t, "ffffffff000000000000000000000000"), 217 z11_networkStr: "2001:db8::/32", 218 z12_octets: []int{0x20, 0x01, 0x0d, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 219 z13_firstUsable: "2001:db8::", 220 z14_lastUsable: "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff", 221 z17_DialPacketArgs: []string{"udp6", ""}, 222 z18_DialStreamArgs: []string{"tcp6", ""}, 223 z19_ListenPacketArgs: []string{"udp6", ""}, 224 z20_ListenStreamArgs: []string{"tcp6", ""}, 225 z99_pass: true, 226 }, 227 { // 10 - IPv6 ::1 228 z00_input: "::1", 229 z01_addrHexStr: "00000000000000000000000000000001", 230 z02_addrBinStr: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", 231 z03_addrStr: "::1", 232 z04_NetIPStringOut: "::1", 233 z05_addrInt: newIPv6Address(t, "00000000000000000000000000000001"), 234 z06_netInt: newIPv6Network(t, "00000000000000000000000000000001"), 235 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 236 z08_maskbits: 128, 237 z09_NetIPNetStringOut: "::1/128", 238 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 239 z11_networkStr: "::1", 240 z12_octets: []int{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, 241 z13_firstUsable: "::1", 242 z14_lastUsable: "::1", 243 z17_DialPacketArgs: []string{"udp6", ""}, 244 z18_DialStreamArgs: []string{"tcp6", ""}, 245 z19_ListenPacketArgs: []string{"udp6", "[::1]:0"}, 246 z20_ListenStreamArgs: []string{"tcp6", "[::1]:0"}, 247 z99_pass: true, 248 }, 249 { // 11 - IPv6 100:: 250 z00_input: "100::", 251 z01_addrHexStr: "01000000000000000000000000000000", 252 z02_addrBinStr: "00000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 253 z03_addrStr: "100::", 254 z04_NetIPStringOut: "100::", 255 z05_addrInt: newIPv6Address(t, "01000000000000000000000000000000"), 256 z06_netInt: newIPv6Network(t, "01000000000000000000000000000000"), 257 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 258 z08_maskbits: 128, 259 z09_NetIPNetStringOut: "100::/128", 260 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 261 z11_networkStr: "100::", 262 z12_octets: []int{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 263 z13_firstUsable: "100::", 264 z14_lastUsable: "100::", 265 z17_DialPacketArgs: []string{"udp6", ""}, 266 z18_DialStreamArgs: []string{"tcp6", ""}, 267 z19_ListenPacketArgs: []string{"udp6", "[100::]:0"}, 268 z20_ListenStreamArgs: []string{"tcp6", "[100::]:0"}, 269 z99_pass: true, 270 }, 271 { // 12 - IPv6 100::2 272 z00_input: "100::2", 273 z01_addrHexStr: "01000000000000000000000000000002", 274 z02_addrBinStr: "00000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", 275 z03_addrStr: "100::2", 276 z04_NetIPStringOut: "100::2", 277 z05_addrInt: newIPv6Address(t, "01000000000000000000000000000002"), 278 z06_netInt: newIPv6Network(t, "01000000000000000000000000000002"), 279 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 280 z08_maskbits: 128, 281 z09_NetIPNetStringOut: "100::2/128", 282 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 283 z11_networkStr: "100::2", 284 z12_octets: []int{0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x02}, 285 z13_firstUsable: "100::2", 286 z14_lastUsable: "100::2", 287 z17_DialPacketArgs: []string{"udp6", ""}, 288 z18_DialStreamArgs: []string{"tcp6", ""}, 289 z19_ListenPacketArgs: []string{"udp6", "[100::2]:0"}, 290 z20_ListenStreamArgs: []string{"tcp6", "[100::2]:0"}, 291 z99_pass: true, 292 }, 293 { // 13 - IPv6 `[100::2]:80` 294 z00_input: "[100::2]:80", 295 z01_addrHexStr: "01000000000000000000000000000002", 296 z02_addrBinStr: "00000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", 297 z03_addrStr: "[100::2]:80", 298 z04_NetIPStringOut: "100::2", 299 z05_addrInt: newIPv6Address(t, "01000000000000000000000000000002"), 300 z06_netInt: newIPv6Network(t, "01000000000000000000000000000002"), 301 z07_ipMaskStr: "ffffffffffffffffffffffffffffffff", 302 z08_maskbits: 128, 303 z09_NetIPNetStringOut: "100::2/128", 304 z10_maskInt: newIPv6Mask(t, "ffffffffffffffffffffffffffffffff"), 305 z11_networkStr: "100::2", 306 z12_octets: []int{0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x02}, 307 z13_firstUsable: "100::2", 308 z14_lastUsable: "100::2", 309 z16_portInt: 80, 310 z17_DialPacketArgs: []string{"udp6", "[100::2]:80"}, 311 z18_DialStreamArgs: []string{"tcp6", "[100::2]:80"}, 312 z19_ListenPacketArgs: []string{"udp6", "[100::2]:80"}, 313 z20_ListenStreamArgs: []string{"tcp6", "[100::2]:80"}, 314 z99_pass: true, 315 }, 316 } 317 318 for idx, test := range tests { 319 t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { 320 ipv6, err := sockaddr.NewIPv6Addr(test.z00_input) 321 if test.z99_pass && err != nil { 322 t.Fatalf("[%d] Unable to create an IPv6Addr from %+q: %v", idx, test.z00_input, err) 323 } else if !test.z99_pass && err == nil { 324 t.Fatalf("[%d] Expected test to fail for %+q", idx, test.z00_input) 325 } else if !test.z99_pass && err != nil { 326 // Expected failure, return success 327 return 328 } 329 330 if type_ := ipv6.Type(); type_ != sockaddr.TypeIPv6 { 331 t.Errorf("[%d] Expected new IPv6Addr to be Type %d, received %d (int)", idx, sockaddr.TypeIPv6, type_) 332 } 333 334 h, ok := ipv6.Host().(sockaddr.IPv6Addr) 335 if !ok { 336 t.Errorf("[%d] Unable to type assert +%q's Host to IPv6Addr", idx, test.z00_input) 337 } 338 339 hAddressBigInt := big.Int(*h.Address) 340 hMaskBigInt := big.Int(*h.Mask) 341 if hAddressBigInt.Cmp(ipv6.Address) != 0 || hMaskBigInt.Cmp(ipv6HostMask) != 0 || h.Port != ipv6.Port { 342 t.Errorf("[%d] Expected %+q's Host() to return identical IPv6Addr except mask, received %+q", idx, test.z00_input, h.String()) 343 } 344 345 if c := cap(*ipv6.NetIP()); c != sockaddr.IPv6len { 346 t.Errorf("[%d] Expected new IPv6Addr's Address capacity to be %d bytes, received %d", idx, sockaddr.IPv6len, c) 347 } 348 349 if l := len(*ipv6.NetIP()); l != sockaddr.IPv6len { 350 t.Errorf("[%d] Expected new IPv6Addr's Address length to be %d bytes, received %d", idx, sockaddr.IPv6len, l) 351 } 352 353 if s := ipv6.AddressHexString(); s != test.z01_addrHexStr { 354 t.Errorf("[%d] Expected address %+q's hexadecimal representation to be %+q, received %+q", idx, test.z00_input, test.z01_addrHexStr, s) 355 } 356 357 if s := ipv6.AddressBinString(); s != test.z02_addrBinStr { 358 t.Errorf("[%d] Expected address %+q's binary representation to be %+q, received %+q", idx, test.z00_input, test.z02_addrBinStr, s) 359 } 360 361 if s := ipv6.String(); s != test.z03_addrStr { 362 t.Errorf("[%d] Expected %+q's String to be %+q, received %+q", idx, test.z00_input, test.z03_addrStr, s) 363 } 364 365 if s := ipv6.NetIP().String(); s != test.z04_NetIPStringOut { 366 t.Errorf("[%d] Expected %+q's address to be %+q, received %+q", idx, test.z00_input, test.z04_NetIPStringOut, s) 367 } 368 369 if hAddressBigInt.Cmp(test.z05_addrInt) != 0 { 370 t.Errorf("[%d] Expected %+q's Address to return %+v, received %+v", idx, test.z00_input, test.z05_addrInt, hAddressBigInt) 371 } 372 373 n, ok := ipv6.Network().(sockaddr.IPv6Addr) 374 if !ok { 375 t.Errorf("[%d] Unable to type assert +%q's Network to IPv6Addr", idx, test.z00_input) 376 } 377 378 nAddressBigInt := big.Int(*n.Address) 379 if nAddressBigInt.Cmp(test.z06_netInt) != 0 { 380 t.Errorf("[%d] Expected %+q's Network to return %+v, received %+v", idx, test.z00_input, test.z06_netInt, n.Address) 381 } 382 383 if m := ipv6.NetIPMask().String(); m != test.z07_ipMaskStr { 384 t.Errorf("[%d] Expected %+q's mask to be %+q, received %+q", idx, test.z00_input, test.z07_ipMaskStr, m) 385 } 386 387 if m := ipv6.Maskbits(); m != test.z08_maskbits { 388 t.Errorf("[%dr] Expected %+q's port to be %+v, received %+v", idx, test.z00_input, test.z08_maskbits, m) 389 } 390 391 if n := ipv6.NetIPNet().String(); n != test.z09_NetIPNetStringOut { 392 t.Errorf("[%d] Expected %+q's network to be %+q, received %+q", idx, test.z00_input, test.z09_NetIPNetStringOut, n) 393 } 394 395 ipv6MaskBigInt := big.Int(*ipv6.Mask) 396 if ipv6MaskBigInt.Cmp(test.z10_maskInt) != 0 { 397 t.Errorf("[%d] Expected %+q's Mask to return %+v, received %+v", idx, test.z00_input, test.z10_maskInt, ipv6MaskBigInt) 398 } 399 400 nMaskBigInt := big.Int(*n.Mask) 401 if nMaskBigInt.Cmp(test.z10_maskInt) != 0 { 402 t.Errorf("[%d] Expected %+q's Network's Mask to return %+v, received %+v", idx, test.z00_input, test.z10_maskInt, nMaskBigInt) 403 } 404 405 // Network()'s mask must match the IPv6Addr's Mask 406 if n := ipv6.Network().String(); n != test.z11_networkStr { 407 t.Errorf("[%d] Expected %+q's Network() to be %+q, received %+q", idx, test.z00_input, test.z11_networkStr, n) 408 } 409 410 if o := ipv6.Octets(); len(o) != 16 || cap(o) != 16 || 411 o[0] != test.z12_octets[0] || o[1] != test.z12_octets[1] || 412 o[2] != test.z12_octets[2] || o[3] != test.z12_octets[3] || 413 o[4] != test.z12_octets[4] || o[5] != test.z12_octets[5] || 414 o[6] != test.z12_octets[6] || o[7] != test.z12_octets[7] || 415 o[8] != test.z12_octets[8] || o[9] != test.z12_octets[9] || 416 o[10] != test.z12_octets[10] || o[11] != test.z12_octets[11] || 417 o[12] != test.z12_octets[12] || o[13] != test.z12_octets[13] || 418 o[14] != test.z12_octets[14] || o[15] != test.z12_octets[15] { 419 t.Errorf("[%d] Expected %+q's Octets to be %x, received %x", idx, test.z00_input, test.z12_octets, o) 420 } 421 422 if f := ipv6.FirstUsable().String(); f != test.z13_firstUsable { 423 t.Errorf("[%d] Expected %+q's FirstUsable() to be %+q, received %+q", idx, test.z00_input, test.z13_firstUsable, f) 424 } 425 426 if l := ipv6.LastUsable().String(); l != test.z14_lastUsable { 427 t.Errorf("[%d] Expected %+q's LastUsable() to be %+q, received %+q", idx, test.z00_input, test.z14_lastUsable, l) 428 } 429 430 if p := ipv6.IPPort(); sockaddr.IPPort(p) != test.z16_portInt { 431 t.Errorf("[%d] Expected %+q's port to be %+v, received %+v", idx, test.z00_input, test.z16_portInt, p) 432 } 433 434 if dialNet, dialArgs := ipv6.DialPacketArgs(); dialNet != test.z17_DialPacketArgs[0] || dialArgs != test.z17_DialPacketArgs[1] { 435 t.Errorf("[%d] Expected %+q's DialPacketArgs() to be %+q, received %+q, %+q", idx, test.z00_input, test.z17_DialPacketArgs, dialNet, dialArgs) 436 } 437 438 if dialNet, dialArgs := ipv6.DialStreamArgs(); dialNet != test.z18_DialStreamArgs[0] || dialArgs != test.z18_DialStreamArgs[1] { 439 t.Errorf("[%d] Expected %+q's DialStreamArgs() to be %+q, received %+q, %+q", idx, test.z00_input, test.z18_DialStreamArgs, dialNet, dialArgs) 440 } 441 442 if listenNet, listenArgs := ipv6.ListenPacketArgs(); listenNet != test.z19_ListenPacketArgs[0] || listenArgs != test.z19_ListenPacketArgs[1] { 443 t.Errorf("[%d] Expected %+q's ListenPacketArgs() to be %+q, received %+q, %+q", idx, test.z00_input, test.z19_ListenPacketArgs, listenNet, listenArgs) 444 } 445 446 if listenNet, listenArgs := ipv6.ListenStreamArgs(); listenNet != test.z20_ListenStreamArgs[0] || listenArgs != test.z20_ListenStreamArgs[1] { 447 t.Errorf("[%d] Expected %+q's ListenStreamArgs() to be %+q, received %+q, %+q", idx, test.z00_input, test.z20_ListenStreamArgs, listenNet, listenArgs) 448 } 449 }) 450 } 451} 452 453func TestSockAddr_IPv6Addr_CmpAddress(t *testing.T) { 454 tests := []struct { 455 a string 456 b string 457 cmp int 458 }{ 459 { // 0 460 a: "2001:4860:0:2001::68/128", 461 b: "2001:4860:0:2001::68", 462 cmp: 0, 463 }, 464 { // 1 465 a: "2607:f0d0:1002:0051:0000:0000:0000:0004/128", 466 b: "2607:f0d0:1002:0051:0000:0000:0000:0004", 467 cmp: 0, 468 }, 469 { // 2 470 a: "2607:f0d0:1002:0051:0000:0000:0000:0004/128", 471 b: "2607:f0d0:1002:0051:0000:0000:0000:0004/64", 472 cmp: 0, 473 }, 474 { // 3 475 a: "2607:f0d0:1002:0051:0000:0000:0000:0004", 476 b: "2607:f0d0:1002:0051:0000:0000:0000:0005", 477 cmp: -1, 478 }, 479 } 480 481 for idx, test := range tests { 482 t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { 483 ipv6a, err := sockaddr.NewIPv6Addr(test.a) 484 if err != nil { 485 t.Fatalf("[%d] Unable to create an IPv6Addr from %+q: %v", idx, test.a, err) 486 } 487 488 ipv6b, err := sockaddr.NewIPv6Addr(test.b) 489 if err != nil { 490 t.Fatalf("[%d] Unable to create an IPv6Addr from %+q: %v", idx, test.b, err) 491 } 492 493 if x := ipv6a.CmpAddress(ipv6b); x != test.cmp { 494 t.Errorf("[%d] IPv6Addr.CmpAddress() failed with %+q with %+q (expected %d, received %d)", idx, ipv6a, ipv6b, test.cmp, x) 495 } 496 497 if x := ipv6b.CmpAddress(ipv6a); x*-1 != test.cmp { 498 t.Errorf("[%d] IPv6Addr.CmpAddress() failed with %+q with %+q (expected %d, received %d)", idx, ipv6a, ipv6b, test.cmp, x) 499 } 500 }) 501 } 502} 503 504func TestSockAddr_IPv6Addr_ContainsAddress(t *testing.T) { 505 tests := []struct { 506 name string 507 input sockaddr.IPv6Addr 508 cases []sockaddr.IPv6Addr 509 fail bool 510 }{ 511 { 512 name: "basic", 513 input: sockaddr.MustIPv6Addr("::1/128"), 514 cases: []sockaddr.IPv6Addr{ 515 sockaddr.MustIPv6Addr("::1"), 516 sockaddr.MustIPv6Addr("[::1/128]"), 517 }, 518 }, 519 { 520 name: "fail", 521 input: sockaddr.MustIPv6Addr("::1/128"), 522 cases: []sockaddr.IPv6Addr{ 523 sockaddr.MustIPv6Addr("100::"), 524 }, 525 fail: true, 526 }, 527 { 528 name: "fail2", 529 input: sockaddr.MustIPv6Addr("100::/128"), 530 cases: []sockaddr.IPv6Addr{ 531 sockaddr.MustIPv6Addr("::1"), 532 }, 533 fail: true, 534 }, 535 } 536 537 for idx, test := range tests { 538 if test.name == "" { 539 t.Fatalf("test %d needs a name", idx) 540 } 541 542 t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { 543 ipv6 := test.input 544 545 for _, tc := range test.cases { 546 if ipv6.ContainsAddress(tc.Address) == test.fail { 547 t.Errorf("%s: Expected %q.ContainsAddress(%q)==%t", test.name, ipv6, tc, test.fail) 548 } 549 } 550 }) 551 } 552} 553 554func TestSockAddr_IPv6Addr_ContainsNetwork(t *testing.T) { 555 tests := []struct { 556 input string 557 pass []string 558 fail []string 559 }{ 560 { // 0 561 input: "::1/128", 562 pass: []string{ 563 "::1", 564 "[::1/128]", 565 }, 566 fail: []string{ 567 "100::", 568 }, 569 }, 570 } 571 572 for idx, test := range tests { 573 t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { 574 ipv6, err := sockaddr.NewIPv6Addr(test.input) 575 if err != nil { 576 t.Fatalf("[%d] Unable to create an IPv6Addr from %+q: %v", idx, test.input, err) 577 } 578 579 for passIdx, passInput := range test.pass { 580 passAddr, err := sockaddr.NewIPv6Addr(passInput) 581 if err != nil { 582 t.Fatalf("[%d/%d] Unable to create an IPv6Addr from %+q: %v", idx, passIdx, passInput, err) 583 } 584 585 if !passAddr.ContainsNetwork(ipv6) { 586 t.Errorf("[%d/%d] Expected %+q to contain %+q", idx, passIdx, test.input, passInput) 587 } 588 } 589 590 for failIdx, failInput := range test.fail { 591 failAddr, err := sockaddr.NewIPv6Addr(failInput) 592 if err != nil { 593 t.Fatalf("[%d/%d] Unable to create an IPv6Addr from %+q: %v", idx, failIdx, failInput, err) 594 } 595 596 if failAddr.ContainsNetwork(ipv6) { 597 t.Errorf("[%d/%d] Expected %+q to contain %+q", idx, failIdx, test.input, failInput) 598 } 599 } 600 }) 601 } 602} 603 604func TestSockAddr_IPv6Addr_Equal(t *testing.T) { 605 tests := []struct { 606 name string 607 input sockaddr.IPv6Addr 608 cases sockaddr.SockAddrs 609 fail bool 610 }{ 611 { 612 name: "addr equal", 613 input: sockaddr.MustIPv6Addr("2001:4860:0:2001::68/128"), 614 cases: sockaddr.SockAddrs{ 615 sockaddr.MustIPv6Addr("2001:4860:0:2001::68"), 616 sockaddr.MustIPv6Addr("2001:4860:0:2001::68/128"), 617 sockaddr.MustIPv6Addr("[2001:4860:0:2001::68]:0"), 618 }, 619 }, 620 { 621 name: "IPv6Addr not equal", 622 input: sockaddr.MustIPv6Addr("2001:4860:0:2001::68/128"), 623 cases: sockaddr.SockAddrs{ 624 sockaddr.MustIPv6Addr("2001:DB8::/48"), 625 sockaddr.MustIPv6Addr("2001:4860:0:2001::67/128"), 626 sockaddr.MustIPv6Addr("2001:4860:0:2001::67"), 627 sockaddr.MustIPv6Addr("[2001:4860:0:2001::68]:80"), 628 sockaddr.MustIPv4Addr("1.2.3.4"), 629 sockaddr.MustUnixSock("/tmp/foo"), 630 }, 631 fail: true, 632 }, 633 { 634 name: "equal CIDR", 635 input: sockaddr.MustIPv6Addr("2001:4860:0:2001::68/64"), 636 cases: sockaddr.SockAddrs{ 637 sockaddr.MustIPv6Addr("2001:4860:0:2001::68/64"), 638 }, 639 }, 640 { 641 name: "not equal CIDR", 642 input: sockaddr.MustIPv6Addr("2001:4860:0:2001::68/64"), 643 cases: sockaddr.SockAddrs{ 644 sockaddr.MustIPv6Addr("2001:DB8::/48"), 645 sockaddr.MustIPv6Addr("2001:4860:0:2001::67/128"), 646 sockaddr.MustIPv6Addr("2001:4860:0:2001::67"), 647 sockaddr.MustIPv6Addr("[2001:4860:0:2001::68]:80"), 648 sockaddr.MustIPv4Addr("1.2.3.4/32"), 649 sockaddr.MustUnixSock("/tmp/foo"), 650 }, 651 fail: true, 652 }, 653 } 654 655 for idx, test := range tests { 656 if test.name == "" { 657 t.Fatalf("test %d needs a name", idx) 658 } 659 660 t.Run(test.name, func(t *testing.T) { 661 ipv6 := test.input 662 for _, tc := range test.cases { 663 if ipv6.Equal(tc) == test.fail { 664 t.Errorf("%s: Expected %s Equal(%q)=%t", test.name, ipv6, tc, test.fail) 665 } 666 } 667 }) 668 } 669} 670 671func TestIPv6Addr_CmpRFC(t *testing.T) { 672 tests := []struct { 673 name string 674 recv sockaddr.SockAddr 675 arg sockaddr.SockAddr 676 rfcNum uint 677 want int 678 }{ 679 { 680 name: "simple in RFC", 681 recv: sockaddr.MustIPv6Addr("::1"), 682 arg: sockaddr.MustIPv6Addr("100::"), 683 rfcNum: 6590, 684 }, 685 { 686 name: "ipv6 cmp IPv4", 687 recv: sockaddr.MustIPv6Addr("2002:c058:6301::/120"), 688 arg: sockaddr.MustIPv4Addr("192.88.99.0/24"), 689 rfcNum: 3068, 690 want: -1, 691 }, 692 { 693 name: "ipv6 cmp IPv4", 694 recv: sockaddr.MustIPv6Addr("::1"), 695 arg: sockaddr.MustIPv4Addr("1.2.3.4"), 696 rfcNum: 6590, 697 }, 698 { 699 name: "ipv6 cmp IPv4", 700 recv: sockaddr.MustIPv6Addr("::1"), 701 arg: sockaddr.MustIPv4Addr("192.168.1.1"), 702 rfcNum: 1918, 703 }, 704 } 705 706 for i, test := range tests { 707 if test.name == "" { 708 t.Fatalf("test %d needs a name", i) 709 } 710 711 t.Run(test.name, func(t *testing.T) { 712 if cmp := test.recv.CmpRFC(test.rfcNum, test.arg); cmp != test.want { 713 t.Fatalf("%s: want %d got %d", test.name, test.want, cmp) 714 } 715 }) 716 } 717} 718 719func TestIPv6Attrs(t *testing.T) { 720 const expectedNumAttrs = 2 721 attrs := sockaddr.IPv6Attrs() 722 if len(attrs) != expectedNumAttrs { 723 t.Fatalf("wrong number of IPv6Attrs: %d vs %d", len(attrs), expectedNumAttrs) 724 } 725} 726