From 091dea6bc33e3b8bcff96b62008eadf7fe2c22ac Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Thu, 10 Dec 2020 15:35:41 -0500 Subject: [PATCH] add more ipv6 utils --- .../cobbzilla/util/network/NetworkUtil.java | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/cobbzilla/util/network/NetworkUtil.java b/src/main/java/org/cobbzilla/util/network/NetworkUtil.java index 3e4305d..d3cb8d6 100644 --- a/src/main/java/org/cobbzilla/util/network/NetworkUtil.java +++ b/src/main/java/org/cobbzilla/util/network/NetworkUtil.java @@ -12,22 +12,24 @@ import java.io.IOException; import java.math.BigInteger; import java.net.*; import java.util.*; +import java.util.function.Predicate; import java.util.stream.Collectors; -import static org.cobbzilla.util.daemon.ZillaRuntime.die; -import static org.cobbzilla.util.daemon.ZillaRuntime.empty; +import static org.cobbzilla.util.daemon.ZillaRuntime.*; import static org.cobbzilla.util.http.HttpSchemes.SCHEME_HTTPS; import static org.cobbzilla.util.http.HttpSchemes.isHttpOrHttps; import static org.cobbzilla.util.http.HttpUtil.url2string; import static org.cobbzilla.util.http.URIUtil.toUri; import static org.cobbzilla.util.string.ValidationRegexes.IPv4_PATTERN; +import static org.cobbzilla.util.string.ValidationRegexes.IPv6_PATTERN; @Slf4j public class NetworkUtil { public static final String IPv4_ALL_ADDRS = "0.0.0.0"; public static final String IPv4_LOCALHOST = "127.0.0.1"; - public static final String IPv6_LOCALHOST = "fd00::1"; + public static final String IPv6_LOCALHOST = "::1"; + public static final String IPv6_LOCALHOST_CIDR = "::1/128"; public static boolean isLocalIpv4(String addr) { if (empty(addr)) return false; @@ -37,6 +39,14 @@ public class NetworkUtil { return false; } + public static boolean isLocalIpv6(String addr) { + if (empty(addr)) return false; + if (addr.startsWith("/")) addr = addr.substring(1); + if (!IPv6_PATTERN.matcher(addr).matches()) return false; + if (addr.equals(IPv6_LOCALHOST) || addr.equals(IPv6_LOCALHOST_CIDR)) return true; + return false; + } + private static final Map localhostCache = new ExpirationMap<>(); public static boolean isLocalHost(String host) { @@ -70,6 +80,20 @@ public class NetworkUtil { } } + public static boolean isPublicIpv6(String addr) { + if (empty(addr)) return false; + if (addr.startsWith("/")) addr = addr.substring(1); + if (!IPv6_PATTERN.matcher(addr).matches()) return false; + try { + final InetAddress address = InetAddress.getByName(addr); + if (address.isSiteLocalAddress() || address.isLoopbackAddress() || address.isLinkLocalAddress()) return false; + return !isLocalIpv6(addr) && !isPrivateIp6(addr); + } catch (Exception e) { + log.warn("isPublicIpv4: "+e); + return false; + } + } + public static boolean isPrivateIp4(String addr) { if (addr.startsWith("10.")) return true; if (addr.startsWith("192.168.")) return true; @@ -83,6 +107,8 @@ public class NetworkUtil { return false; } + public static boolean isPrivateIp6(String addr) { return addr.startsWith("fd"); } + public static String getEthernetIpv4(NetworkInterface iface) { if (iface == null) return null; if (!iface.getName().startsWith(getEthernetInterfacePrefix())) return null; @@ -120,11 +146,12 @@ public class NetworkUtil { } } } - return die("getLocalhostIpv4: no local 127.x.x.x address found"); + log.warn("getLocalhostIpv4: no local 127.x.x.x address found (returning 127.0.0.1)"); } catch (Exception e) { - return die("getLocalhostIpv4: "+e, e); + log.warn("getLocalhostIpv4 (returning 127.0.0.1): "+shortError(e)); } + return IPv4_LOCALHOST; } public static Set configuredIps() { @@ -164,6 +191,14 @@ public class NetworkUtil { } public static String getFirstPublicIpv4() { + return getFirstAddrMatch(NetworkUtil::isPublicIpv4); + } + + public static String getFirstPublicIpv6() { + return getFirstAddrMatch(NetworkUtil::isPublicIpv4); + } + + private static String getFirstAddrMatch(Predicate predicate) { try { final Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { @@ -171,16 +206,16 @@ public class NetworkUtil { final Enumeration addrs = i.getInetAddresses(); while (addrs.hasMoreElements()) { final String addr = addrs.nextElement().toString(); - if (isPublicIpv4(addr)) { + if (predicate.test(addr)) { return addr.substring(1); } } } - log.debug("getFirstPublicIpv4: no public IPv4 address found"); + log.debug("getFirstAddrMatch: no matching address found"); return null; } catch (Exception e) { - return die("getFirstPublicIpv4: "+e, e); + return die("getFirstAddrMatch: "+e, e); } }