github.com/cilium/cilium@v1.16.2/pkg/ip/ip_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package ip 5 6 import ( 7 "math/big" 8 "net" 9 "net/netip" 10 "sort" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 ) 15 16 type IPTestSuite struct{} 17 18 func setupIPTestSuite(_ testing.TB) *IPTestSuite { 19 return &IPTestSuite{} 20 } 21 22 func TestCountIPs(t *testing.T) { 23 tests := map[string]*big.Int{ 24 "192.168.0.1/32": big.NewInt(0), 25 "192.168.0.1/31": big.NewInt(0).Sub(big.NewInt(1), big.NewInt(1)), 26 "192.168.0.1/30": big.NewInt(2), 27 "192.168.0.1/24": big.NewInt(254), 28 "192.168.0.1/16": big.NewInt(65534), 29 "::1/128": big.NewInt(0), 30 "::1/120": big.NewInt(254), 31 "fd02:1::/32": big.NewInt(0).Sub(big.NewInt(2).Exp(big.NewInt(2), big.NewInt(96), nil), big.NewInt(2)), 32 } 33 for cidr, nIPs := range tests { 34 _, ipnet, err := net.ParseCIDR(cidr) 35 require.Nil(t, err) 36 count := CountIPsInCIDR(ipnet) 37 require.EqualValues(t, nIPs, count) 38 } 39 } 40 41 func TestFirstIP(t *testing.T) { 42 // Test IPv4. 43 desiredIPv4_1 := net.IP{0xa, 0, 0, 0} 44 testNetv4_1 := net.IPNet{IP: net.ParseIP("10.0.0.5"), Mask: net.CIDRMask(8, 32)} 45 ipNetv4_1 := getNetworkPrefix(&testNetv4_1) 46 for k := range *ipNetv4_1 { 47 require.Equal(t, desiredIPv4_1[k], (*ipNetv4_1)[k]) 48 } 49 testNetv4_2 := net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: net.CIDRMask(8, 32)} 50 ipNetv4_2 := getNetworkPrefix(&testNetv4_2) 51 for k := range *ipNetv4_2 { 52 require.Equal(t, desiredIPv4_1[k], (*ipNetv4_2)[k]) 53 } 54 55 // Test IPv6 56 desiredIPv6_1, testNetv6_1, _ := net.ParseCIDR("fd44:7089:ff32:712b::/64") 57 58 ipNetv6_1 := getNetworkPrefix(testNetv6_1) 59 for k := range *ipNetv6_1 { 60 require.Equal(t, desiredIPv6_1[k], (*ipNetv6_1)[k]) 61 } 62 } 63 64 func (s *IPTestSuite) testIPNetsEqual(created, expected []*net.IPNet, t *testing.T) { 65 require.Len(t, created, len(expected)) 66 for index := range created { 67 require.Equal(t, expected[index].String(), created[index].String()) 68 require.Equal(t, expected[index].Mask.String(), created[index].Mask.String()) 69 } 70 } 71 72 func (s *IPTestSuite) testIPsEqual(created, expected net.IP, t *testing.T) { 73 require.Len(t, created, len(expected)) 74 for k := range created { 75 require.Equal(t, expected[k], created[k]) 76 } 77 } 78 79 func createIPNet(address string, maskSize int, bitLen int) *net.IPNet { 80 return &net.IPNet{IP: net.ParseIP(address), Mask: net.CIDRMask(maskSize, bitLen)} 81 } 82 83 func createIPRange(first string, last string) *netWithRange { 84 firstIP := net.ParseIP(first) 85 lastIP := net.ParseIP(last) 86 return &netWithRange{First: &firstIP, Last: &lastIP} 87 } 88 89 func TestRemoveRedundant(t *testing.T) { 90 s := setupIPTestSuite(t) 91 92 CIDRs := []*net.IPNet{ 93 createIPNet("10.96.0.0", 12, ipv4BitLen), 94 createIPNet("10.112.0.0", 13, ipv4BitLen), 95 } 96 expectedCIDRs := []*net.IPNet{ 97 createIPNet("10.96.0.0", 12, ipv4BitLen), 98 createIPNet("10.112.0.0", 13, ipv4BitLen), 99 } 100 nonRedundantCIDRs := removeRedundantCIDRs(CIDRs) 101 s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t) 102 103 CIDRs = []*net.IPNet{ 104 createIPNet("10.96.0.0", 11, ipv4BitLen), 105 createIPNet("10.112.0.0", 12, ipv4BitLen), 106 } 107 expectedCIDRs = []*net.IPNet{ 108 createIPNet("10.96.0.0", 11, ipv4BitLen), 109 } 110 nonRedundantCIDRs = removeRedundantCIDRs(CIDRs) 111 s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t) 112 113 CIDRs = []*net.IPNet{ 114 createIPNet("10.112.0.0", 12, ipv4BitLen), 115 createIPNet("10.96.0.0", 11, ipv4BitLen), 116 } 117 nonRedundantCIDRs = removeRedundantCIDRs(CIDRs) 118 s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t) 119 120 CIDRs = []*net.IPNet{ 121 createIPNet("10.120.0.0", 13, ipv4BitLen), 122 createIPNet("10.93.0.4", 30, ipv4BitLen), 123 createIPNet("10.112.0.0", 12, ipv4BitLen), 124 createIPNet("10.62.0.33", 32, ipv4BitLen), 125 createIPNet("10.96.0.0", 11, ipv4BitLen), 126 } 127 expectedCIDRs = []*net.IPNet{ 128 createIPNet("10.93.0.4", 30, ipv4BitLen), 129 createIPNet("10.62.0.33", 32, ipv4BitLen), 130 createIPNet("10.96.0.0", 11, ipv4BitLen), 131 } 132 nonRedundantCIDRs = removeRedundantCIDRs(CIDRs) 133 s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t) 134 135 CIDRs = []*net.IPNet{ 136 createIPNet("10.120.0.0", 13, ipv4BitLen), 137 createIPNet("10.93.0.4", 30, ipv4BitLen), 138 createIPNet("10.93.0.4", 30, ipv4BitLen), 139 createIPNet("10.112.0.0", 12, ipv4BitLen), 140 createIPNet("10.62.0.33", 32, ipv4BitLen), 141 createIPNet("10.96.0.0", 11, ipv4BitLen), 142 } 143 expectedCIDRs = []*net.IPNet{ 144 createIPNet("10.93.0.4", 30, ipv4BitLen), 145 createIPNet("10.62.0.33", 32, ipv4BitLen), 146 createIPNet("10.96.0.0", 11, ipv4BitLen), 147 } 148 nonRedundantCIDRs = removeRedundantCIDRs(CIDRs) 149 s.testIPNetsEqual(nonRedundantCIDRs, expectedCIDRs, t) 150 } 151 152 func TestRemoveCIDRs(t *testing.T) { 153 s := setupIPTestSuite(t) 154 155 allowCIDRs := []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)} 156 removeCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 12, ipv4BitLen), 157 createIPNet("10.112.0.0", 13, ipv4BitLen), 158 } 159 expectedCIDRs := []*net.IPNet{createIPNet("10.128.0.0", 9, ipv4BitLen), 160 createIPNet("10.0.0.0", 10, ipv4BitLen), 161 createIPNet("10.64.0.0", 11, ipv4BitLen), 162 createIPNet("10.120.0.0", 13, ipv4BitLen)} 163 allowedCIDRs := RemoveCIDRs(allowCIDRs, removeCIDRs) 164 s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t) 165 166 // Removing superset removes the allowed CIDR 167 allowCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 12, ipv4BitLen)} 168 removeCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)} 169 expectedCIDRs = []*net.IPNet{} 170 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 171 s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t) 172 173 allowCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)} 174 removeCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 12, ipv4BitLen), 175 createIPNet("10.112.0.0", 13, ipv4BitLen), 176 createIPNet("10.62.0.33", 32, ipv4BitLen), 177 createIPNet("10.93.0.4", 30, ipv4BitLen), 178 createIPNet("10.63.0.5", 13, ipv4BitLen), 179 } 180 expectedCIDRs = []*net.IPNet{createIPNet("10.128.0.0", 9, ipv4BitLen), 181 createIPNet("10.0.0.0", 11, ipv4BitLen), 182 createIPNet("10.32.0.0", 12, ipv4BitLen), 183 createIPNet("10.48.0.0", 13, ipv4BitLen), 184 createIPNet("10.120.0.0", 13, ipv4BitLen), 185 createIPNet("10.64.0.0", 12, ipv4BitLen), 186 createIPNet("10.80.0.0", 13, ipv4BitLen), 187 createIPNet("10.88.0.0", 14, ipv4BitLen), 188 createIPNet("10.94.0.0", 15, ipv4BitLen), 189 createIPNet("10.92.0.0", 16, ipv4BitLen), 190 createIPNet("10.93.128.0", 17, ipv4BitLen), 191 createIPNet("10.93.64.0", 18, ipv4BitLen), 192 createIPNet("10.93.32.0", 19, ipv4BitLen), 193 createIPNet("10.93.16.0", 20, ipv4BitLen), 194 createIPNet("10.93.8.0", 21, ipv4BitLen), 195 createIPNet("10.93.4.0", 22, ipv4BitLen), 196 createIPNet("10.93.2.0", 23, ipv4BitLen), 197 createIPNet("10.93.1.0", 24, ipv4BitLen), 198 createIPNet("10.93.0.128", 25, ipv4BitLen), 199 createIPNet("10.93.0.64", 26, ipv4BitLen), 200 createIPNet("10.93.0.32", 27, ipv4BitLen), 201 createIPNet("10.93.0.16", 28, ipv4BitLen), 202 createIPNet("10.93.0.8", 29, ipv4BitLen), 203 createIPNet("10.93.0.0", 30, ipv4BitLen), 204 } 205 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 206 s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t) 207 208 // Cannot remove CIDRs that are of a different address family. 209 allowCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)} 210 removeCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b::", 66, ipv6BitLen)} 211 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 212 s.testIPNetsEqual(allowedCIDRs, allowCIDRs, t) 213 214 allowCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)} 215 removeCIDRs = []*net.IPNet{createIPNet("a000::", 8, ipv6BitLen)} 216 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 217 s.testIPNetsEqual(allowedCIDRs, allowCIDRs, t) 218 219 allowCIDRs = []*net.IPNet{createIPNet("a000::", 8, ipv6BitLen)} 220 removeCIDRs = []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen)} 221 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 222 s.testIPNetsEqual(allowedCIDRs, allowCIDRs, t) 223 224 //IPv6 tests 225 allowCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b:ff00::", 64, ipv6BitLen)} 226 removeCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b::", 66, ipv6BitLen)} 227 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 228 expectedCIDRs = []*net.IPNet{createIPNet("fd44:7089:ff32:712b:8000::", 65, ipv6BitLen), 229 createIPNet("fd44:7089:ff32:712b:4000::", 66, ipv6BitLen)} 230 s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t) 231 232 } 233 234 func TestRemoveSameCIDR(t *testing.T) { 235 allowCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 32, ipv4BitLen)} 236 237 allowedCIDRs := RemoveCIDRs(allowCIDRs, allowCIDRs) 238 require.Len(t, allowedCIDRs, 0) 239 } 240 241 func TestRemoveCIDRsEdgeCases(t *testing.T) { 242 s := setupIPTestSuite(t) 243 244 // Remote some /32s 245 allowCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 30, ipv4BitLen)} 246 removeCIDRs := []*net.IPNet{createIPNet("10.96.0.0", 32, ipv4BitLen), createIPNet("10.96.0.1", 32, ipv4BitLen)} 247 expectedCIDRs := []*net.IPNet{createIPNet("10.96.0.2", 31, ipv4BitLen)} 248 allowedCIDRs := RemoveCIDRs(allowCIDRs, removeCIDRs) 249 s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t) 250 251 // Remove some subnets 252 allowCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 22, ipv4BitLen)} 253 removeCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 24, ipv4BitLen), createIPNet("10.96.1.0", 24, ipv4BitLen)} 254 expectedCIDRs = []*net.IPNet{createIPNet("10.96.2.0", 23, ipv4BitLen)} 255 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 256 s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t) 257 258 // Remove all subnets 259 allowCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 23, ipv4BitLen)} 260 removeCIDRs = []*net.IPNet{createIPNet("10.96.0.0", 24, ipv4BitLen), createIPNet("10.96.1.0", 24, ipv4BitLen)} 261 expectedCIDRs = []*net.IPNet{} 262 allowedCIDRs = RemoveCIDRs(allowCIDRs, removeCIDRs) 263 s.testIPNetsEqual(allowedCIDRs, expectedCIDRs, t) 264 } 265 266 func TestByteFunctions(t *testing.T) { 267 //flipNthHighestBit 268 testBytes := net.IP{0x0, 0x0, 0x0, 0x0} 269 expectedBytes := net.IP{0x0, 0x0, 0x0, 0x80} 270 flipNthHighestBit(testBytes, 24) 271 for k := range expectedBytes { 272 require.Equal(t, testBytes[k], expectedBytes[k]) 273 } 274 275 testBytes = net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0} 276 expectedBytes = net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0} 277 flipNthHighestBit(testBytes, 95) 278 for k := range expectedBytes { 279 require.Equal(t, testBytes[k], expectedBytes[k]) 280 } 281 } 282 283 func TestIPNetToRange(t *testing.T) { 284 s := setupIPTestSuite(t) 285 286 testRange := ipNetToRange(*createIPNet("192.0.128.0", 24, ipv4BitLen)) 287 var expectedFirst, expectedLast []byte 288 expectedFirst = append(expectedFirst, v4Mappedv6Prefix...) 289 expectedFirst = append(expectedFirst, []byte{192, 0, 128, 0}...) 290 expectedFirstIP := net.IP(expectedFirst) 291 292 expectedLast = append(expectedLast, v4Mappedv6Prefix...) 293 expectedLast = append(expectedLast, []byte{192, 0, 128, 255}...) 294 expectedLastIP := net.IP(expectedLast) 295 expectedRange := netWithRange{First: &expectedFirstIP, Last: &expectedLastIP} 296 297 s.checkRangesEqual(&expectedRange, &testRange, t) 298 299 // Check that all bits are masked correctly. 300 testRange = ipNetToRange(*createIPNet("192.0.128.255", 24, ipv4BitLen)) 301 s.checkRangesEqual(&expectedRange, &testRange, t) 302 303 testRange = ipNetToRange(*createIPNet("fd44:7089:ff32:712b:ff00::", 64, ipv6BitLen)) 304 testRange = ipNetToRange(*createIPNet("::ffff:0", 128, ipv6BitLen)) 305 306 } 307 308 func (s *IPTestSuite) checkRangesEqual(range1, range2 *netWithRange, t *testing.T) { 309 for l := range *range1.First { 310 require.Equal(t, (*range2.First)[l], (*range1.First)[l]) 311 } 312 for l := range *range1.Last { 313 require.Equal(t, (*range2.Last)[l], (*range1.Last)[l]) 314 } 315 } 316 317 func TestNetsByRange(t *testing.T) { 318 s := setupIPTestSuite(t) 319 320 ranges := []*netWithRange{} 321 322 // Check sorting by last IP first 323 cidrs := []*net.IPNet{createIPNet("10.0.0.0", 8, ipv4BitLen), 324 createIPNet("10.0.0.0", 10, ipv4BitLen), 325 createIPNet("10.64.0.0", 11, ipv4BitLen), 326 createIPNet("10.112.0.0", 12, ipv4BitLen)} 327 328 for _, network := range cidrs { 329 newNetToRange := ipNetToRange(*network) 330 ranges = append(ranges, &newNetToRange) 331 } 332 333 expectedRanges := []*netWithRange{ 334 createIPRange("10.0.0.0", "10.63.255.255"), 335 createIPRange("10.64.0.0", "10.95.255.255"), 336 createIPRange("10.112.0.0", "10.127.255.255"), 337 createIPRange("10.0.0.0", "10.255.255.255")} 338 sort.Sort(NetsByRange(ranges)) 339 // Ensure that length of ranges isn't modified first. 340 require.Equal(t, len(expectedRanges), len(ranges)) 341 for k := range ranges { 342 s.checkRangesEqual(ranges[k], expectedRanges[k], t) 343 } 344 345 ranges = []*netWithRange{createIPRange("10.0.0.0", "10.255.255.255"), 346 createIPRange("10.255.255.254", "10.255.255.255")} 347 expectedRanges = []*netWithRange{createIPRange("10.0.0.0", "10.255.255.255"), 348 createIPRange("10.255.255.254", "10.255.255.255")} 349 sort.Sort(NetsByRange(ranges)) 350 // Ensure that length of ranges isn't modified first. 351 require.Equal(t, len(expectedRanges), len(ranges)) 352 for k := range ranges { 353 s.checkRangesEqual(ranges[k], expectedRanges[k], t) 354 } 355 356 } 357 358 func TestCoalesceCIDRs(t *testing.T) { 359 s := setupIPTestSuite(t) 360 361 cidrs := []*net.IPNet{createIPNet("192.0.128.0", 24, ipv4BitLen), 362 createIPNet("192.0.129.0", 24, ipv4BitLen)} 363 expected := []*net.IPNet{createIPNet("192.0.128.0", 23, ipv4BitLen)} 364 mergedV4CIDRs, mergedV6CIDRs := CoalesceCIDRs(cidrs) 365 require.Equal(t, 0, len(mergedV6CIDRs)) 366 s.testIPNetsEqual(mergedV4CIDRs, expected, t) 367 368 cidrs = []*net.IPNet{createIPNet("192.0.129.0", 24, ipv4BitLen), 369 createIPNet("192.0.130.0", 24, ipv4BitLen)} 370 expected = []*net.IPNet{createIPNet("192.0.129.0", 24, ipv4BitLen), 371 createIPNet("192.0.130.0", 24, ipv4BitLen)} 372 mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs) 373 require.Equal(t, 0, len(mergedV6CIDRs)) 374 s.testIPNetsEqual(mergedV4CIDRs, expected, t) 375 376 cidrs = []*net.IPNet{createIPNet("192.0.2.112", 30, ipv4BitLen), 377 createIPNet("192.0.2.116", 31, ipv4BitLen), 378 createIPNet("192.0.2.118", 31, ipv4BitLen)} 379 expected = []*net.IPNet{createIPNet("192.0.2.112", 29, ipv4BitLen)} 380 mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs) 381 require.Equal(t, 0, len(mergedV6CIDRs)) 382 s.testIPNetsEqual(mergedV4CIDRs, expected, t) 383 384 cidrs = []*net.IPNet{createIPNet("192.0.2.112", 30, ipv4BitLen), 385 createIPNet("192.0.2.116", 32, ipv4BitLen), 386 createIPNet("192.0.2.118", 31, ipv4BitLen)} 387 expected = []*net.IPNet{createIPNet("192.0.2.112", 30, ipv4BitLen), 388 createIPNet("192.0.2.116", 32, ipv4BitLen), 389 createIPNet("192.0.2.118", 31, ipv4BitLen)} 390 mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs) 391 require.Equal(t, 0, len(mergedV6CIDRs)) 392 s.testIPNetsEqual(mergedV4CIDRs, expected, t) 393 394 cidrs = []*net.IPNet{createIPNet("192.0.2.112", 31, ipv4BitLen), 395 createIPNet("192.0.2.116", 31, ipv4BitLen), 396 createIPNet("192.0.2.118", 31, ipv4BitLen)} 397 expected = []*net.IPNet{createIPNet("192.0.2.112", 31, ipv4BitLen), 398 createIPNet("192.0.2.116", 30, ipv4BitLen)} 399 mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs) 400 require.Equal(t, 0, len(mergedV6CIDRs)) 401 s.testIPNetsEqual(mergedV4CIDRs, expected, t) 402 403 cidrs = []*net.IPNet{createIPNet("192.0.1.254", 31, ipv4BitLen), 404 createIPNet("192.0.2.0", 28, ipv4BitLen), 405 createIPNet("192.0.2.16", 28, ipv4BitLen), 406 createIPNet("192.0.2.32", 28, ipv4BitLen), 407 createIPNet("192.0.2.48", 28, ipv4BitLen), 408 createIPNet("192.0.2.64", 28, ipv4BitLen), 409 createIPNet("192.0.2.80", 28, ipv4BitLen), 410 createIPNet("192.0.2.96", 28, ipv4BitLen), 411 createIPNet("192.0.2.112", 28, ipv4BitLen), 412 createIPNet("192.0.2.128", 28, ipv4BitLen), 413 createIPNet("192.0.2.144", 28, ipv4BitLen), 414 createIPNet("192.0.2.160", 28, ipv4BitLen), 415 createIPNet("192.0.2.176", 28, ipv4BitLen), 416 createIPNet("192.0.2.192", 28, ipv4BitLen), 417 createIPNet("192.0.2.208", 28, ipv4BitLen), 418 createIPNet("192.0.2.224", 28, ipv4BitLen), 419 createIPNet("192.0.2.240", 28, ipv4BitLen), 420 createIPNet("192.0.3.0", 28, ipv4BitLen), 421 } 422 423 expected = []*net.IPNet{createIPNet("192.0.1.254", 31, ipv4BitLen), 424 createIPNet("192.0.2.0", 24, ipv4BitLen), 425 createIPNet("192.0.3.0", 28, ipv4BitLen)} 426 mergedV4CIDRs, mergedV6CIDRs = CoalesceCIDRs(cidrs) 427 require.Equal(t, 0, len(mergedV6CIDRs)) 428 s.testIPNetsEqual(mergedV4CIDRs, expected, t) 429 430 cidrs = []*net.IPNet{createIPNet("::", 0, ipv6BitLen), 431 createIPNet("fe80::1", 128, ipv6BitLen)} 432 expected = []*net.IPNet{createIPNet("::", 0, ipv6BitLen)} 433 _, mergedV6CIDRs = CoalesceCIDRs(cidrs) 434 s.testIPNetsEqual(mergedV6CIDRs, expected, t) 435 436 // assert cidr_merge(['::/0', '::192.0.2.0/124', 'ff00::101']) == [IPNetwork('::/0')] 437 cidrs = []*net.IPNet{createIPNet("::", 0, ipv6BitLen), 438 createIPNet("::192.0.2.0", 124, ipv6BitLen), 439 createIPNet("ff00::101", 128, ipv6BitLen)} 440 _, mergedV6CIDRs = CoalesceCIDRs(cidrs) 441 s.testIPNetsEqual(mergedV6CIDRs, expected, t) 442 } 443 444 func TestRangeToCIDRs(t *testing.T) { 445 // IPv4 worst case. 446 ipNets := rangeToCIDRs(net.ParseIP("0.0.0.1"), net.ParseIP("255.255.255.254")) 447 expected := []*net.IPNet{createIPNet("0.0.0.1", 32, ipv4BitLen), 448 createIPNet("0.0.0.2", 31, ipv4BitLen), 449 createIPNet("0.0.0.4", 30, ipv4BitLen), 450 createIPNet("0.0.0.8", 29, ipv4BitLen), 451 createIPNet("0.0.0.16", 28, ipv4BitLen), 452 createIPNet("0.0.0.32", 27, ipv4BitLen), 453 createIPNet("0.0.0.64", 26, ipv4BitLen), 454 createIPNet("0.0.0.128", 25, ipv4BitLen), 455 createIPNet("0.0.1.0", 24, ipv4BitLen), 456 createIPNet("0.0.2.0", 23, ipv4BitLen), 457 createIPNet("0.0.4.0", 22, ipv4BitLen), 458 createIPNet("0.0.8.0", 21, ipv4BitLen), 459 createIPNet("0.0.16.0", 20, ipv4BitLen), 460 createIPNet("0.0.32.0", 19, ipv4BitLen), 461 createIPNet("0.0.64.0", 18, ipv4BitLen), 462 createIPNet("0.0.128.0", 17, ipv4BitLen), 463 createIPNet("0.1.0.0", 16, ipv4BitLen), 464 createIPNet("0.2.0.0", 15, ipv4BitLen), 465 createIPNet("0.4.0.0", 14, ipv4BitLen), 466 createIPNet("0.8.0.0", 13, ipv4BitLen), 467 createIPNet("0.16.0.0", 12, ipv4BitLen), 468 createIPNet("0.32.0.0", 11, ipv4BitLen), 469 createIPNet("0.64.0.0", 10, ipv4BitLen), 470 createIPNet("0.128.0.0", 9, ipv4BitLen), 471 createIPNet("1.0.0.0", 8, ipv4BitLen), 472 createIPNet("2.0.0.0", 7, ipv4BitLen), 473 createIPNet("4.0.0.0", 6, ipv4BitLen), 474 createIPNet("8.0.0.0", 5, ipv4BitLen), 475 createIPNet("16.0.0.0", 4, ipv4BitLen), 476 createIPNet("32.0.0.0", 3, ipv4BitLen), 477 createIPNet("64.0.0.0", 2, ipv4BitLen), 478 createIPNet("128.0.0.0", 2, ipv4BitLen), 479 createIPNet("192.0.0.0", 3, ipv4BitLen), 480 createIPNet("224.0.0.0", 4, ipv4BitLen), 481 createIPNet("240.0.0.0", 5, ipv4BitLen), 482 createIPNet("248.0.0.0", 6, ipv4BitLen), 483 createIPNet("252.0.0.0", 7, ipv4BitLen), 484 createIPNet("254.0.0.0", 8, ipv4BitLen), 485 createIPNet("255.0.0.0", 9, ipv4BitLen), 486 createIPNet("255.128.0.0", 10, ipv4BitLen), 487 createIPNet("255.192.0.0", 11, ipv4BitLen), 488 createIPNet("255.224.0.0", 12, ipv4BitLen), 489 createIPNet("255.240.0.0", 13, ipv4BitLen), 490 createIPNet("255.248.0.0", 14, ipv4BitLen), 491 createIPNet("255.252.0.0", 15, ipv4BitLen), 492 createIPNet("255.254.0.0", 16, ipv4BitLen), 493 createIPNet("255.255.0.0", 17, ipv4BitLen), 494 createIPNet("255.255.128.0", 18, ipv4BitLen), 495 createIPNet("255.255.192.0", 19, ipv4BitLen), 496 createIPNet("255.255.224.0", 20, ipv4BitLen), 497 createIPNet("255.255.240.0", 21, ipv4BitLen), 498 createIPNet("255.255.249.0", 22, ipv4BitLen), 499 createIPNet("255.255.252.0", 23, ipv4BitLen), 500 createIPNet("255.255.254.0", 24, ipv4BitLen), 501 createIPNet("255.255.255.0", 25, ipv4BitLen), 502 createIPNet("255.255.255.128", 26, ipv4BitLen), 503 createIPNet("255.255.255.192", 27, ipv4BitLen), 504 createIPNet("255.255.255.224", 28, ipv4BitLen), 505 createIPNet("255.255.255.240", 29, ipv4BitLen), 506 createIPNet("255.255.255.248", 30, ipv4BitLen), 507 createIPNet("255.255.255.252", 31, ipv4BitLen), 508 createIPNet("255.255.255.254", 32, ipv4BitLen), 509 } 510 511 // Sort both so we can compare easily 512 sort.Sort(NetsByMask(expected)) 513 sort.Sort(NetsByMask(ipNets)) 514 require.Equal(t, len(expected), len(ipNets)) 515 } 516 517 func TestPreviousIP(t *testing.T) { 518 s := setupIPTestSuite(t) 519 520 ip := net.ParseIP("10.0.0.0") 521 expectedPrev := net.ParseIP("9.255.255.255") 522 prevIP := getPreviousIP(ip) 523 s.testIPsEqual(prevIP, expectedPrev, t) 524 525 // Check that underflow does not occur. 526 ip = net.ParseIP("0.0.0.0") 527 prevIP = getPreviousIP(ip) 528 expectedPrev = ip 529 s.testIPsEqual(prevIP, expectedPrev, t) 530 531 ip = net.ParseIP("::") 532 prevIP = getPreviousIP(ip) 533 expectedPrev = ip 534 s.testIPsEqual(prevIP, expectedPrev, t) 535 536 ip = net.ParseIP("10.0.0.1") 537 prevIP = getPreviousIP(ip) 538 expectedPrev = net.ParseIP("10.0.0.0") 539 s.testIPsEqual(prevIP, expectedPrev, t) 540 541 ip = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") 542 expectedPrev = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe") 543 prevIP = getPreviousIP(ip) 544 s.testIPsEqual(prevIP, expectedPrev, t) 545 } 546 547 func TestNextIP(t *testing.T) { 548 expectedNext := net.ParseIP("10.0.0.0") 549 ip := net.ParseIP("9.255.255.255") 550 nextIP := GetNextIP(ip) 551 require.EqualValues(t, expectedNext, nextIP) 552 553 // Check that overflow does not occur. 554 ip = net.ParseIP("255.255.255.255") 555 nextIP = GetNextIP(ip) 556 expectedNext = ip 557 require.EqualValues(t, expectedNext, nextIP) 558 559 ip = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") 560 nextIP = GetNextIP(ip) 561 expectedNext = ip 562 require.EqualValues(t, expectedNext, nextIP) 563 564 ip = []byte{0xa, 0, 0, 0} 565 nextIP = GetNextIP(ip) 566 expectedNext = []byte{0xa, 0, 0, 1} 567 require.EqualValues(t, expectedNext, nextIP) 568 569 ip = []byte{0xff, 0xff, 0xff, 0xff} 570 nextIP = GetNextIP(ip) 571 expectedNext = []byte{0xff, 0xff, 0xff, 0xff} 572 require.EqualValues(t, expectedNext, nextIP) 573 574 ip = net.ParseIP("10.0.0.0") 575 nextIP = GetNextIP(ip) 576 expectedNext = net.ParseIP("10.0.0.1") 577 require.EqualValues(t, expectedNext, nextIP) 578 579 ip = net.ParseIP("0:0:0:0:ffff:ffff:ffff:ffff") 580 nextIP = GetNextIP(ip) 581 expectedNext = net.ParseIP("0:0:0:1:0:0:0:0") 582 require.EqualValues(t, expectedNext, nextIP) 583 584 ip = net.ParseIP("ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff") 585 nextIP = GetNextIP(ip) 586 expectedNext = net.ParseIP("ffff:ffff:ffff:ffff:0:0:0:0") 587 require.EqualValues(t, expectedNext, nextIP) 588 589 ip = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe") 590 nextIP = GetNextIP(ip) 591 expectedNext = net.ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") 592 require.EqualValues(t, expectedNext, nextIP) 593 } 594 595 func TestCreateSpanningCIDR(t *testing.T) { 596 s := setupIPTestSuite(t) 597 598 netRange := createIPRange("10.0.0.0", "10.255.255.255") 599 expectedSpanningCIDR := createIPNet("10.0.0.0", 8, ipv4BitLen) 600 spanningCIDR := createSpanningCIDR(*netRange) 601 s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t) 602 603 netRange = createIPRange("10.0.0.0", "10.255.255.254") 604 expectedSpanningCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen) 605 spanningCIDR = createSpanningCIDR(*netRange) 606 s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t) 607 608 netRange = createIPRange("10.0.0.1", "10.0.0.1") 609 expectedSpanningCIDR = createIPNet("10.0.0.1", 32, ipv4BitLen) 610 spanningCIDR = createSpanningCIDR(*netRange) 611 s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t) 612 613 netRange = createIPRange("10.0.0.1", "10.0.0.2") 614 expectedSpanningCIDR = createIPNet("10.0.0.0", 30, ipv4BitLen) 615 spanningCIDR = createSpanningCIDR(*netRange) 616 s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t) 617 618 netRange = createIPRange("9.0.0.0", "10.0.0.0") 619 expectedSpanningCIDR = createIPNet("8.0.0.0", 6, ipv4BitLen) 620 spanningCIDR = createSpanningCIDR(*netRange) 621 s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t) 622 623 netRange = createIPRange("FD44:7089:FF32:712B:FF00:0000:0000:0000", "FD44:7089:FF32:712B:FFFF:FFFF:FFFF:FFFF") 624 expectedSpanningCIDR = createIPNet("fd44:7089:ff32:712b:ff00::", 72, ipv6BitLen) 625 spanningCIDR = createSpanningCIDR(*netRange) 626 s.testIPNetsEqual([]*net.IPNet{expectedSpanningCIDR}, []*net.IPNet{&spanningCIDR}, t) 627 628 } 629 630 func TestPartitionCIDR(t *testing.T) { 631 s := setupIPTestSuite(t) 632 633 targetCIDR := createIPNet("10.0.0.0", 8, ipv4BitLen) 634 excludeCIDR := createIPNet("10.255.255.255", 32, ipv4BitLen) 635 left, exclude, right := PartitionCIDR(*targetCIDR, *excludeCIDR) 636 // Exclude should just contain exclude CIDR 637 s.testIPNetsEqual([]*net.IPNet{excludeCIDR}, exclude, t) 638 // Nothing should be in right list. 639 require.Equal(t, 0, len(right)) 640 expectedLeft := []*net.IPNet{createIPNet("10.0.0.0", 9, ipv4BitLen), 641 createIPNet("10.128.0.0", 10, ipv4BitLen), 642 createIPNet("10.192.0.0", 11, ipv4BitLen), 643 createIPNet("10.224.0.0", 12, ipv4BitLen), 644 createIPNet("10.240.0.0", 13, ipv4BitLen), 645 createIPNet("10.248.0.0", 14, ipv4BitLen), 646 createIPNet("10.252.0.0", 15, ipv4BitLen), 647 createIPNet("10.254.0.0", 16, ipv4BitLen), 648 createIPNet("10.255.0.0", 17, ipv4BitLen), 649 createIPNet("10.255.128.0", 18, ipv4BitLen), 650 createIPNet("10.255.192.0", 19, ipv4BitLen), 651 createIPNet("10.255.224.0", 20, ipv4BitLen), 652 createIPNet("10.255.240.0", 21, ipv4BitLen), 653 createIPNet("10.255.248.0", 22, ipv4BitLen), 654 createIPNet("10.255.252.0", 23, ipv4BitLen), 655 createIPNet("10.255.254.0", 24, ipv4BitLen), 656 createIPNet("10.255.255.0", 25, ipv4BitLen), 657 createIPNet("10.255.255.128", 26, ipv4BitLen), 658 createIPNet("10.255.255.192", 27, ipv4BitLen), 659 createIPNet("10.255.255.224", 28, ipv4BitLen), 660 createIPNet("10.255.255.240", 29, ipv4BitLen), 661 createIPNet("10.255.255.248", 30, ipv4BitLen), 662 createIPNet("10.255.255.252", 31, ipv4BitLen), 663 createIPNet("10.255.255.254", 32, ipv4BitLen), 664 } 665 s.testIPNetsEqual(expectedLeft, left, t) 666 667 targetCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen) 668 excludeCIDR = createIPNet("10.0.0.0", 32, ipv4BitLen) 669 left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR) 670 // Exclude should just contain exclude CIDR 671 s.testIPNetsEqual([]*net.IPNet{excludeCIDR}, exclude, t) 672 // Nothing should be in left list. 673 require.Equal(t, 0, len(left)) 674 expectedRight := []*net.IPNet{createIPNet("10.128.0.0", 9, ipv4BitLen), 675 createIPNet("10.64.0.0", 10, ipv4BitLen), 676 createIPNet("10.32.0.0", 11, ipv4BitLen), 677 createIPNet("10.16.0.0", 12, ipv4BitLen), 678 createIPNet("10.8.0.0", 13, ipv4BitLen), 679 createIPNet("10.4.0.0", 14, ipv4BitLen), 680 createIPNet("10.2.0.0", 15, ipv4BitLen), 681 createIPNet("10.1.0.0", 16, ipv4BitLen), 682 createIPNet("10.0.128.0", 17, ipv4BitLen), 683 createIPNet("10.0.64.0", 18, ipv4BitLen), 684 createIPNet("10.0.32.0", 19, ipv4BitLen), 685 createIPNet("10.0.16.0", 20, ipv4BitLen), 686 createIPNet("10.0.8.0", 21, ipv4BitLen), 687 createIPNet("10.0.4.0", 22, ipv4BitLen), 688 createIPNet("10.0.2.0", 23, ipv4BitLen), 689 createIPNet("10.0.1.0", 24, ipv4BitLen), 690 createIPNet("10.0.0.128", 25, ipv4BitLen), 691 createIPNet("10.0.0.64", 26, ipv4BitLen), 692 createIPNet("10.0.0.32", 27, ipv4BitLen), 693 createIPNet("10.0.0.16", 28, ipv4BitLen), 694 createIPNet("10.0.0.8", 29, ipv4BitLen), 695 createIPNet("10.0.0.4", 30, ipv4BitLen), 696 createIPNet("10.0.0.2", 31, ipv4BitLen), 697 createIPNet("10.0.0.1", 32, ipv4BitLen), 698 } 699 s.testIPNetsEqual(expectedRight, right, t) 700 701 // exclude is not in target CIDR and is to left. 702 targetCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen) 703 excludeCIDR = createIPNet("9.0.0.255", 32, ipv4BitLen) 704 left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR) 705 require.Equal(t, 0, len(left)) 706 require.Equal(t, 0, len(exclude)) 707 s.testIPNetsEqual([]*net.IPNet{targetCIDR}, right, t) 708 709 // exclude is not in target CIDR and is to right. 710 targetCIDR = createIPNet("10.255.255.254", 32, ipv4BitLen) 711 excludeCIDR = createIPNet("10.255.255.255", 32, ipv4BitLen) 712 left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR) 713 require.Equal(t, 0, len(right)) 714 require.Equal(t, 0, len(exclude)) 715 s.testIPNetsEqual([]*net.IPNet{targetCIDR}, left, t) 716 717 // exclude CIDR larger than target CIDR 718 targetCIDR = createIPNet("10.96.0.0", 12, ipv4BitLen) 719 excludeCIDR = createIPNet("10.0.0.0", 8, ipv4BitLen) 720 left, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR) 721 require.Equal(t, 0, len(left)) 722 require.Equal(t, 0, len(right)) 723 s.testIPNetsEqual([]*net.IPNet{targetCIDR}, exclude, t) 724 725 targetCIDR = createIPNet("fd44:7089:ff32:712b:ff00::", 64, ipv6BitLen) 726 excludeCIDR = createIPNet("fd44:7089:ff32:712b::", 66, ipv6BitLen) 727 728 _, exclude, right = PartitionCIDR(*targetCIDR, *excludeCIDR) 729 730 expectedCIDRs := []*net.IPNet{createIPNet("fd44:7089:ff32:712b:8000::", 65, ipv6BitLen), 731 createIPNet("fd44:7089:ff32:712b:4000::", 66, ipv6BitLen)} 732 s.testIPNetsEqual(expectedCIDRs, right, t) 733 s.testIPNetsEqual([]*net.IPNet{excludeCIDR}, exclude, t) 734 } 735 736 func TestKeepUniqueAddrs(t *testing.T) { 737 for _, tc := range []struct { 738 name string 739 addrs []netip.Addr 740 want []netip.Addr 741 }{ 742 { 743 name: "nil slice", 744 addrs: nil, 745 want: nil, 746 }, 747 { 748 name: "empty slice", 749 addrs: []netip.Addr{}, 750 want: []netip.Addr{}, 751 }, 752 { 753 name: "one element slice", 754 addrs: []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 755 want: []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 756 }, 757 { 758 name: "IPv4 all duplicates", 759 addrs: []netip.Addr{ 760 netip.MustParseAddr("1.1.1.1"), 761 netip.MustParseAddr("1.1.1.1"), 762 netip.MustParseAddr("1.1.1.1"), 763 }, 764 want: []netip.Addr{ 765 netip.MustParseAddr("1.1.1.1"), 766 }, 767 }, 768 { 769 name: "IPv4 all unique", 770 addrs: []netip.Addr{ 771 netip.MustParseAddr("1.1.1.1"), 772 netip.MustParseAddr("2.2.2.2"), 773 netip.MustParseAddr("3.3.3.3"), 774 }, 775 want: []netip.Addr{ 776 netip.MustParseAddr("1.1.1.1"), 777 netip.MustParseAddr("2.2.2.2"), 778 netip.MustParseAddr("3.3.3.3"), 779 }, 780 }, 781 { 782 name: "IPv4 mixed", 783 addrs: []netip.Addr{ 784 netip.MustParseAddr("3.3.3.3"), 785 netip.MustParseAddr("1.1.1.1"), 786 netip.MustParseAddr("2.2.2.2"), 787 netip.MustParseAddr("2.2.2.2"), 788 }, 789 want: []netip.Addr{ 790 netip.MustParseAddr("1.1.1.1"), 791 netip.MustParseAddr("2.2.2.2"), 792 netip.MustParseAddr("3.3.3.3"), 793 }, 794 }, 795 { 796 name: "IPv6 all duplicates", 797 addrs: []netip.Addr{ 798 netip.MustParseAddr("f00d::1"), 799 netip.MustParseAddr("f00d::1"), 800 netip.MustParseAddr("f00d::1"), 801 }, 802 want: []netip.Addr{ 803 netip.MustParseAddr("f00d::1"), 804 }, 805 }, 806 { 807 name: "Mixed IPv4 & IPv6", 808 addrs: []netip.Addr{ 809 netip.MustParseAddr("::1"), 810 netip.MustParseAddr("f00d::1"), 811 netip.MustParseAddr("1.1.1.1"), 812 netip.MustParseAddr("f00d::1"), 813 }, 814 want: []netip.Addr{ 815 netip.MustParseAddr("1.1.1.1"), 816 netip.MustParseAddr("::1"), 817 netip.MustParseAddr("f00d::1"), 818 }, 819 }, 820 { 821 name: "With IPv6-in-IPv6", 822 addrs: []netip.Addr{ 823 netip.MustParseAddr("::ffff:0101:0101"), 824 netip.MustParseAddr("::ffff:1.1.1.1"), 825 netip.MustParseAddr("1.1.1.1"), 826 }, 827 want: []netip.Addr{ 828 netip.MustParseAddr("1.1.1.1"), 829 netip.MustParseAddr("::ffff:1.1.1.1"), 830 }, 831 }, 832 } { 833 t.Run(tc.name, func(t *testing.T) { 834 got := KeepUniqueAddrs(tc.addrs) 835 if len(tc.want) != len(got) { 836 t.Errorf("%s: KeepUniqueAddrs(%q): got %d unique addresses, want %d", 837 tc.name, tc.addrs, len(got), len(tc.want)) 838 } 839 for i := range got { 840 if tc.want[i] != got[i] { 841 t.Errorf("%s: KeepUniqueAddrs(%q): mismatching address at index %d: got %v, want %v", 842 tc.name, tc.addrs, i, got[i], tc.want[i]) 843 } 844 } 845 }) 846 } 847 } 848 849 func TestIPVersion(t *testing.T) { 850 type args struct { 851 ip net.IP 852 } 853 tests := []struct { 854 name string 855 args args 856 v4 bool 857 v6 bool 858 }{ 859 { 860 name: "test-1", 861 args: args{ 862 ip: nil, 863 }, 864 v4: false, 865 v6: false, 866 }, 867 { 868 name: "test-2", 869 args: args{ 870 ip: net.ParseIP("1.1.1.1"), 871 }, 872 v4: true, 873 v6: false, 874 }, 875 { 876 name: "test-3", 877 args: args{ 878 ip: net.ParseIP("fd00::1"), 879 }, 880 v4: false, 881 v6: true, 882 }, 883 } 884 for _, tt := range tests { 885 got := IsIPv4(tt.args.ip) 886 require.EqualValuesf(t, tt.v4, got, "v4 test Name: %s", tt.name) 887 888 got = IsIPv6(tt.args.ip) 889 require.EqualValuesf(t, tt.v6, got, "v6 test Name: %s", tt.name) 890 } 891 } 892 893 func TestIPListEquals(t *testing.T) { 894 ips := []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("fd00::1"), net.ParseIP("8.8.8.8")} 895 sorted := []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("8.8.8.8"), net.ParseIP("fd00::1")} 896 897 require.Equal(t, true, UnsortedIPListsAreEqual(ips, sorted)) 898 } 899 900 func TestGetIPFromListByFamily(t *testing.T) { 901 tests := []struct { 902 name string 903 ips []net.IP 904 needsV4Family bool 905 wants net.IP 906 }{ 907 { 908 name: "test-1", 909 ips: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("fd00::1"), net.ParseIP("8.8.8.8")}, 910 needsV4Family: true, 911 wants: net.ParseIP("1.1.1.1"), 912 }, 913 { 914 name: "test-2", 915 ips: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("fd00::1"), net.ParseIP("8.8.8.8")}, 916 needsV4Family: false, 917 wants: net.ParseIP("fd00::1"), 918 }, 919 { 920 name: "test-2", 921 ips: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("8.8.8.8")}, 922 needsV4Family: false, 923 wants: nil, 924 }, 925 } 926 927 for _, tt := range tests { 928 got := GetIPFromListByFamily(tt.ips, tt.needsV4Family) 929 require.EqualValuesf(t, tt.wants.String(), got.String(), "Test Name: %s", tt.name) 930 } 931 } 932 933 func TestGetIPAtIndex(t *testing.T) { 934 type args struct { 935 cidr string 936 index int64 937 want net.IP 938 } 939 940 tests := []args{ 941 { 942 cidr: "10.0.0.0/29", 943 index: -1, 944 want: net.ParseIP("10.0.0.7"), 945 }, { 946 cidr: "10.0.0.0/29", 947 index: 0, 948 want: net.ParseIP("10.0.0.0"), 949 }, { 950 cidr: "10.0.0.0/29", 951 index: 1, 952 want: net.ParseIP("10.0.0.1"), 953 }, { 954 cidr: "10.0.0.16/28", 955 index: -3, 956 want: net.ParseIP("10.0.0.29"), 957 }, { 958 cidr: "10.0.0.0/29", 959 index: -3, 960 want: net.ParseIP("10.0.0.5"), 961 }, { 962 cidr: "10.0.0.0/25", 963 index: -3, 964 want: net.ParseIP("10.0.0.125"), 965 }, { 966 cidr: "10.0.0.128/25", 967 index: -3, 968 want: net.ParseIP("10.0.0.253"), 969 }, { 970 cidr: "10.0.8.0/21", 971 index: -3, 972 want: net.ParseIP("10.0.15.253"), 973 }, { 974 cidr: "fd00::/64", 975 index: -3, 976 want: net.ParseIP("fd00::ffff:ffff:ffff:fffd"), 977 }, 978 } 979 for _, tt := range tests { 980 _, ipNet, _ := net.ParseCIDR(tt.cidr) 981 if got := GetIPAtIndex(*ipNet, tt.index); !got.Equal(tt.want) { 982 t.Errorf("GetIPAtIndex() = %v, want %v", got, tt.want) 983 } 984 } 985 } 986 987 func TestAddrFromIP(t *testing.T) { 988 type args struct { 989 ip net.IP 990 wantAddr netip.Addr 991 wantOk bool 992 } 993 994 tests := []args{ 995 { 996 net.ParseIP("10.0.0.1"), 997 netip.MustParseAddr("10.0.0.1"), 998 true, 999 }, 1000 { 1001 net.ParseIP("a::1"), 1002 netip.MustParseAddr("a::1"), 1003 true, 1004 }, 1005 { 1006 net.ParseIP("::ffff:10.0.0.1"), 1007 netip.MustParseAddr("10.0.0.1"), 1008 true, 1009 }, 1010 } 1011 for _, tt := range tests { 1012 addr, ok := AddrFromIP(tt.ip) 1013 if ok != tt.wantOk { 1014 t.Errorf("AddrFromIP(net.IP(%v)) should success", []byte(tt.ip)) 1015 } 1016 1017 if addr != tt.wantAddr { 1018 t.Errorf("AddrFromIP(net.IP(%v)) = %v want %v", []byte(tt.ip), addr, tt.wantAddr) 1019 } 1020 } 1021 } 1022 1023 func TestMustAddrsFromIPs(t *testing.T) { 1024 type args struct { 1025 ips []net.IP 1026 addrs []netip.Addr 1027 } 1028 for _, tt := range []args{ 1029 { 1030 ips: []net.IP{}, 1031 addrs: []netip.Addr{}, 1032 }, 1033 { 1034 ips: []net.IP{net.ParseIP("1.1.1.1")}, 1035 addrs: []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 1036 }, 1037 { 1038 ips: []net.IP{net.ParseIP("1.1.1.1"), net.ParseIP("2.2.2.2"), net.ParseIP("0.0.0.0")}, 1039 addrs: []netip.Addr{netip.MustParseAddr("1.1.1.1"), netip.MustParseAddr("2.2.2.2"), netip.MustParseAddr("0.0.0.0")}, 1040 }, 1041 } { 1042 addrs := MustAddrsFromIPs(tt.ips) 1043 require.EqualValues(t, tt.addrs, addrs) 1044 } 1045 1046 nilIPs := []net.IP{nil} 1047 defer func() { 1048 if r := recover(); r == nil { 1049 t.Errorf("MustAddrsFromIPs(%v) should panic", nilIPs) 1050 } 1051 }() 1052 _ = MustAddrsFromIPs(nilIPs) 1053 } 1054 1055 func TestPrefixToIpsValidIPv4(t *testing.T) { 1056 prefix := "192.168.1.0/30" 1057 expectedIPs := []string{"192.168.1.0", "192.168.1.1", "192.168.1.2", "192.168.1.3"} 1058 ips, err := PrefixToIps(prefix, 0) 1059 require.Nil(t, err) 1060 require.EqualValues(t, expectedIPs, ips) 1061 } 1062 1063 func TestPrefixToIpsValidLimitedIPv4(t *testing.T) { 1064 prefix := "192.168.1.0/28" 1065 expectedIPs := []string{"192.168.1.0", "192.168.1.1", "192.168.1.2", "192.168.1.3"} 1066 ips, err := PrefixToIps(prefix, 4) 1067 require.Nil(t, err) 1068 require.EqualValues(t, expectedIPs, ips) 1069 } 1070 1071 func TestPrefixToIpsValidIPv6(t *testing.T) { 1072 prefix := "2001:DB8::/126" 1073 expectedIPs := []string{"2001:db8::", "2001:db8::1", "2001:db8::2", "2001:db8::3"} 1074 ips, err := PrefixToIps(prefix, 0) 1075 require.Nil(t, err) 1076 require.EqualValues(t, expectedIPs, ips) 1077 } 1078 1079 func TestPrefixToIpsValidLimitedIPv6(t *testing.T) { 1080 prefix := "2001:DB8::/80" 1081 expectedIPs := []string{"2001:db8::", "2001:db8::1", "2001:db8::2", "2001:db8::3"} 1082 ips, err := PrefixToIps(prefix, 4) 1083 require.Nil(t, err) 1084 require.EqualValues(t, expectedIPs, ips) 1085 } 1086 1087 func TestPrefixToIPsInvalidPrefix(t *testing.T) { 1088 prefix := "invalid" 1089 ips, err := PrefixToIps(prefix, 0) 1090 require.Error(t, err) 1091 require.Len(t, ips, 0) 1092 } 1093 1094 func TestPrefixToIPv4sEdgeCase(t *testing.T) { 1095 prefix := "192.168.1.255/32" 1096 expectedIPs := []string{"192.168.1.255"} 1097 ips, err := PrefixToIps(prefix, 0) 1098 require.Nil(t, err) 1099 require.EqualValues(t, expectedIPs, ips) 1100 } 1101 1102 func TestPrefixToIpsWithMaxIPv4sExceedingRange(t *testing.T) { 1103 prefix := "192.168.1.0/30" 1104 maxIPs := 10 // Intentionally exceeding the available IPs in the prefix 1105 expectedIPs := []string{"192.168.1.0", "192.168.1.1", "192.168.1.2", "192.168.1.3"} 1106 ips, err := PrefixToIps(prefix, maxIPs) 1107 require.Nil(t, err) 1108 require.EqualValues(t, expectedIPs, ips) 1109 }