package org.langke.common.server; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import org.langke.util.logging.ESLogger; import org.langke.util.logging.Loggers; /* * @copyright (c) langke 2011 * @author langke 2011-5-1 */ public class NetworkUtils { private final static ESLogger logger = Loggers.getLogger(NetworkUtils.class); public static enum StackType { IPv4, IPv6, Unknown; } public static final String IPv4_SETTING = "java.net.preferIPv4Stack"; public static final String IPv6_SETTING = "java.net.preferIPv6Addresses"; public static final String NON_LOOPBACK_ADDRESS = "non_loopback_address"; private final static InetAddress localAddress; static { InetAddress localAddressX = null; try { localAddressX = InetAddress.getLocalHost(); } catch (UnknownHostException e) { logger.warn("Failed to find local host", e); } localAddress = localAddressX; } public static Boolean defaultReuseAddress() { return true; // return OsUtils.WINDOWS ? null : true; } public static boolean isIPv4() { return System.getProperty("java.net.preferIPv4Stack") != null && System.getProperty("java.net.preferIPv4Stack") .equals("true"); } public static InetAddress getIPv4Localhost() throws UnknownHostException { return getLocalhost(StackType.IPv4); } public static InetAddress getIPv6Localhost() throws UnknownHostException { return getLocalhost(StackType.IPv6); } public static InetAddress getLocalAddress() { return localAddress; } public static InetAddress getLocalhost(StackType ip_version) throws UnknownHostException { if (ip_version == StackType.IPv4) return InetAddress.getByName("127.0.0.1"); else return InetAddress.getByName("::1"); } public static boolean canBindToMcastAddress() { return true; // return OsUtils.LINUX || OsUtils.SOLARIS || OsUtils.HP; } /** * Returns the first non-loopback address on any interface on the current * host. * * @param ip_version * Constraint on IP version of address to be returned, 4 or 6 */ public static InetAddress getFirstNonLoopbackAddress(StackType ip_version) throws SocketException { try { return InetAddress.getLocalHost(); } catch (UnknownHostException e) { throw new RuntimeException(e); } } /** * Returns the first non-loopback address on the given interface on the * current host. * * @param intf * the interface to be checked * @param ipVersion * Constraint on IP version of address to be returned, 4 or 6 */ public static InetAddress getFirstNonLoopbackAddress(NetworkInterface intf, StackType ipVersion) throws SocketException { if (intf == null) throw new IllegalArgumentException( "Network interface pointer is null"); for (Enumeration<InetAddress> addresses = intf.getInetAddresses(); addresses.hasMoreElements();) { InetAddress address = (InetAddress) addresses.nextElement(); if (!address.isLoopbackAddress()) { if ((address instanceof Inet4Address && ipVersion == StackType.IPv4) || (address instanceof Inet6Address && ipVersion == StackType.IPv6)) return address; } } return null; } /** * A function to check if an interface supports an IP version (i.e has * addresses defined for that IP version). * * @param intf * @return */ public static boolean interfaceHasIPAddresses(NetworkInterface intf, StackType ipVersion) throws SocketException, UnknownHostException { boolean supportsVersion = false; if (intf != null) { // get all the InetAddresses defined on the interface Enumeration<InetAddress> addresses = intf.getInetAddresses(); while (addresses != null && addresses.hasMoreElements()) { // get the next InetAddress for the current interface InetAddress address = (InetAddress) addresses.nextElement(); // check if we find an address of correct version if ((address instanceof Inet4Address && (ipVersion == StackType.IPv4)) || (address instanceof Inet6Address && (ipVersion == StackType.IPv6))) { supportsVersion = true; break; } } } else { throw new UnknownHostException("network interface " + intf + " not found"); } return supportsVersion; } /** * Tries to determine the type of IP stack from the available interfaces and * their addresses and from the system properties (java.net.preferIPv4Stack * and java.net.preferIPv6Addresses) * * @return StackType.IPv4 for an IPv4 only stack, StackYTypeIPv6 for an IPv6 * only stack, and StackType.Unknown if the type cannot be detected */ public static StackType getIpStackType() { boolean isIPv4StackAvailable = isStackAvailable(true); boolean isIPv6StackAvailable = isStackAvailable(false); // if only IPv4 stack available if (isIPv4StackAvailable && !isIPv6StackAvailable) { return StackType.IPv4; } // if only IPv6 stack available else if (isIPv6StackAvailable && !isIPv4StackAvailable) { return StackType.IPv6; } // if dual stack else if (isIPv4StackAvailable && isIPv6StackAvailable) { // get the System property which records user preference for a stack // on a dual stack machine if (Boolean.getBoolean(IPv4_SETTING)) // has preference over // java.net.preferIPv6Addresses return StackType.IPv4; if (Boolean.getBoolean(IPv6_SETTING)) return StackType.IPv6; return StackType.IPv6; } return StackType.Unknown; } public static boolean isStackAvailable(boolean ipv4) { Collection<InetAddress> allAddrs = getAllAvailableAddresses(); for (InetAddress addr : allAddrs) if (ipv4 && addr instanceof Inet4Address || (!ipv4 && addr instanceof Inet6Address)) return true; return false; } public static List<NetworkInterface> getAllAvailableInterfaces() throws SocketException { List<NetworkInterface> allInterfaces = new ArrayList<NetworkInterface>( 10); NetworkInterface intf; for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en .hasMoreElements();) { intf = (NetworkInterface) en.nextElement(); allInterfaces.add(intf); } return allInterfaces; } public static Collection<InetAddress> getAllAvailableAddresses() { Set<InetAddress> retval = new HashSet<InetAddress>(); Enumeration<NetworkInterface> en; try { en = NetworkInterface.getNetworkInterfaces(); if (en == null) return retval; while (en.hasMoreElements()) { NetworkInterface intf = (NetworkInterface) en.nextElement(); Enumeration<InetAddress> addrs = intf.getInetAddresses(); while (addrs.hasMoreElements()) retval.add(addrs.nextElement()); } } catch (SocketException e) { logger.warn("Failed to derive all available interfaces", e); } return retval; } static public int getNextAliablePort(String address, int startport) throws UnknownHostException { InetAddress a = InetAddress.getByName(address); return getNextAliablePort(a, startport); } static public int getNextAliablePort(InetAddress address, int startport) { int port = startport; while (port < 65535) { try { Socket socket = new Socket(address, port); socket.close(); port++; } catch (Exception ex) { return port; } } return -1; } private NetworkUtils() { } public static void main(String[] ss) { try { System.out.println(getNextAliablePort("10.10.10.201", 10000)); } catch (Exception e) { e.printStackTrace(); } } }