package fetchguard import "net/netip" // privateV4 is a literal port of ManualCoverUrlFetcher.php PRIVATE_V4_CIDRS. var privateV4 = []netip.Prefix{ netip.MustParsePrefix("127.0.0.0/8"), netip.MustParsePrefix("10.0.0.0/8"), netip.MustParsePrefix("172.16.0.0/12"), netip.MustParsePrefix("192.168.0.0/16"), netip.MustParsePrefix("169.254.0.0/16"), netip.MustParsePrefix("100.64.0.0/10"), netip.MustParsePrefix("0.0.0.0/8"), } // privateV6 is a literal port of PRIVATE_V6_PREFIXES. PHP lists bare "::1" // as a prefix-less loopback literal; it is expressed here as ::1/128 so // Prefix.Contains works uniformly with the CIDR entries. var privateV6 = []netip.Prefix{ netip.MustParsePrefix("::1/128"), netip.MustParsePrefix("fe80::/10"), netip.MustParsePrefix("fc00::/7"), } // isReservedOrPrivate classifies addr against the PHP private/loopback/ // reserved/CGNAT table. The caller must pass an already-Unmap()-ed address // (fetch.go's dial hook); this function does not Unmap. func isReservedOrPrivate(addr netip.Addr) bool { if !addr.IsValid() { return true } if addr.IsMulticast() || addr.IsUnspecified() { return true } table := privateV4 if !addr.Is4() { table = privateV6 } for _, prefix := range table { if prefix.Contains(addr) { return true } } return false }