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