v1.16.9
ADDED: * netx.IsPub * encodingx/hexx Rest are mostly small corrections and docs
This commit is contained in:
@@ -455,6 +455,82 @@ func IsPrefixNet(s string) (isNet bool) {
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
IsPublic returns true if ALL of the following conditions are *true* for ip:
|
||||
|
||||
* [net/netip.Addr.IsGlobalUnicast]
|
||||
* [net/netip.Addr.IsValid]
|
||||
* (IPv4) Is not in 192.0.2.0/24, 198.51.100.0/24, or 203.0.113.0/24 ([RFC 5737])
|
||||
* (IPv6) Is not in 2001:db8::/32 or 3fff::/20 ([RFC 3849], [RFC 9637])
|
||||
|
||||
AND ALL of the following conditions are *false* for ip:
|
||||
|
||||
* [net/netip.Addr.IsLinkLocalMulticast]
|
||||
* [net/netip.Addr.IsInterfaceLocalMulticast]
|
||||
* [net/netip.Addr.IsLinkLocalUnicast]
|
||||
* [net/netip.Addr.IsMulticast]
|
||||
* [net/netip.Addr.IsLoopback]
|
||||
* [net/netip.Addr.IsPrivate]
|
||||
* [net/netip.Addr.IsUnspecified]
|
||||
|
||||
4-in-6 addresses (::0:0/96, "IPv4-Compatible IPv6 Address" [RFC 4291 § 2.5.5.1] (Legacy/Obsolete);
|
||||
::ffff:0:0/96, "IPv4-Mapped IPv6" [RFC 4291 § 2.5.5.2]) will be internally
|
||||
"unwrapped" back to native IPv4 before performing conditional checks.
|
||||
|
||||
[RFC 5737]: https://datatracker.ietf.org/doc/html/rfc5737
|
||||
[RFC 4291 § 2.5.5.1]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.1
|
||||
[RFC 4291 § 2.5.5.2]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2
|
||||
[RFC 3849]: https://datatracker.ietf.org/doc/html/rfc3849
|
||||
[RFC 9637]: https://datatracker.ietf.org/doc/html/rfc9637
|
||||
*/
|
||||
func IsPublic(ip netip.Addr) (isPub bool) {
|
||||
|
||||
var err error
|
||||
var v bool
|
||||
var addr netip.Addr
|
||||
|
||||
// Clone to avoid modification to the passed in value.
|
||||
if addr, err = netip.ParseAddr(ip.String()); err != nil {
|
||||
return
|
||||
}
|
||||
addr = addr.Unmap()
|
||||
|
||||
// Short-circuit on invalid first to avoid any possible logic oddness.
|
||||
if !addr.IsValid() {
|
||||
return
|
||||
}
|
||||
// Following must be FALSE
|
||||
for _, v = range []bool{
|
||||
addr.IsLinkLocalMulticast(),
|
||||
addr.IsInterfaceLocalMulticast(),
|
||||
addr.IsLinkLocalUnicast(),
|
||||
addr.IsMulticast(),
|
||||
addr.IsLoopback(),
|
||||
addr.IsPrivate(),
|
||||
addr.IsUnspecified(),
|
||||
// these are in the FALSE to keep syntax pattern but it's cleaner to doc as if it's a !<cond> in TRUE.
|
||||
ip4In6Legacy.Contains(ip),
|
||||
ip4In6Modern.Contains(ip),
|
||||
} {
|
||||
if v {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Following must be TRUE
|
||||
for _, v = range []bool{
|
||||
addr.IsGlobalUnicast(),
|
||||
} {
|
||||
if !v {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// All conditions pass
|
||||
isPub = true
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
Mask4ToCidr converts an IPv4 netmask *in bitmask form* to a CIDR prefix size/bit size/bit length.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user