/* * Copyright Ericsson AB 2011-2014. All Rights Reserved. * * The contents of this file are subject to the Lesser GNU Public License, * (the "License"), either version 2.1 of the License, or * (at your option) any later version.; you may not use this file except in * compliance with the License. You should have received a copy of the * License along with this software. If not, it can be * retrieved online at https://www.gnu.org/licenses/lgpl.html. Moreover * it could also be requested from Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO * WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. * EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR * OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, * EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE * LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. * * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING * WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR * REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR * DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL * DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY * (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED * INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE * OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH * HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * */ package com.ericsson.deviceaccess.coap.basedriver.util; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public enum NetUtil { /** * Singleton. */ INSTANCE; private static final Logger LOGGER = LoggerFactory.getLogger(NetUtil.class); static public final int IPV4_ONLY = 1; static public final int IPV6_ONLY = 2; static public final int ADDR_FAMILY_PRIORITISED_IPV4 = 3; static public final int ADDR_FAMILY_PRIORITISED_IPV6 = 4; static public final int ADDR_SCOPE_PRIORITISED_IPV4 = 5; static public final int ADDR_SCOPE_PRIORITISED_IPV6 = 6; private static InetAddress[] getGlobalI() throws SocketException { final ArrayList<InetAddress> inetAddrList = new ArrayList(); Enumeration<NetworkInterface> eNetIf = NetworkInterface.getNetworkInterfaces(); while (eNetIf.hasMoreElements()) { Enumeration<InetAddress> eInetAddr = eNetIf.nextElement().getInetAddresses(); while (eInetAddr.hasMoreElements()) { InetAddress inetAddr = eInetAddr.nextElement(); if (!inetAddr.isAnyLocalAddress() && !inetAddr.isLinkLocalAddress() && !inetAddr.isLoopbackAddress() && !inetAddr.isMulticastAddress()) { inetAddrList.add(inetAddr); } } } return inetAddrList.toArray(new InetAddress[inetAddrList.size()]); } static public InetAddress[] getGlobalInetAddress() throws SocketException { final ArrayList<InetAddress> inetAddrList = new ArrayList(); Enumeration<NetworkInterface> eNetIf = NetworkInterface.getNetworkInterfaces(); while (eNetIf.hasMoreElements()) { Enumeration<InetAddress> eInetAddr = eNetIf.nextElement().getInetAddresses(); while (eInetAddr.hasMoreElements()) { InetAddress inetAddr = eInetAddr.nextElement(); if (!inetAddr.isAnyLocalAddress() && !inetAddr.isLinkLocalAddress() && !inetAddr.isLoopbackAddress() && !inetAddr.isMulticastAddress()) { inetAddrList.add(inetAddr); } } } return inetAddrList.toArray(new InetAddress[inetAddrList.size()]); } public static InetAddress getMyInetAddress(int mode) { List<List<InetAddress>> listOfAddrs = new ArrayList(); ClassifiedAddresses classifiedAddrs = new ClassifiedAddresses(); switch (mode) { case IPV4_ONLY: listOfAddrs.add(classifiedAddrs.globalIPv4); listOfAddrs.add(classifiedAddrs.siteLocalIPv4); listOfAddrs.add(classifiedAddrs.linkLocalIPv4); break; case IPV6_ONLY: listOfAddrs.add(classifiedAddrs.globalIPv6); listOfAddrs.add(classifiedAddrs.siteLocalIPv6); listOfAddrs.add(classifiedAddrs.linkLocalIPv6); break; case ADDR_FAMILY_PRIORITISED_IPV4: listOfAddrs.add(classifiedAddrs.globalIPv4); listOfAddrs.add(classifiedAddrs.siteLocalIPv4); listOfAddrs.add(classifiedAddrs.linkLocalIPv4); listOfAddrs.add(classifiedAddrs.globalIPv6); listOfAddrs.add(classifiedAddrs.siteLocalIPv6); listOfAddrs.add(classifiedAddrs.linkLocalIPv6); break; case ADDR_FAMILY_PRIORITISED_IPV6: listOfAddrs.add(classifiedAddrs.globalIPv6); listOfAddrs.add(classifiedAddrs.siteLocalIPv6); listOfAddrs.add(classifiedAddrs.linkLocalIPv6); listOfAddrs.add(classifiedAddrs.globalIPv4); listOfAddrs.add(classifiedAddrs.siteLocalIPv4); listOfAddrs.add(classifiedAddrs.linkLocalIPv4); break; case ADDR_SCOPE_PRIORITISED_IPV4: listOfAddrs.add(classifiedAddrs.globalIPv4); listOfAddrs.add(classifiedAddrs.globalIPv6); listOfAddrs.add(classifiedAddrs.siteLocalIPv4); listOfAddrs.add(classifiedAddrs.siteLocalIPv6); listOfAddrs.add(classifiedAddrs.linkLocalIPv4); listOfAddrs.add(classifiedAddrs.linkLocalIPv6); break; case ADDR_SCOPE_PRIORITISED_IPV6: default: listOfAddrs.add(classifiedAddrs.globalIPv6); listOfAddrs.add(classifiedAddrs.globalIPv4); listOfAddrs.add(classifiedAddrs.siteLocalIPv6); listOfAddrs.add(classifiedAddrs.siteLocalIPv4); listOfAddrs.add(classifiedAddrs.linkLocalIPv6); listOfAddrs.add(classifiedAddrs.linkLocalIPv4); break; } for (List<InetAddress> addrs : listOfAddrs) { if (!addrs.isEmpty()) { return addrs.get(0); } } try { if (mode == IPV4_ONLY || mode == ADDR_FAMILY_PRIORITISED_IPV4 || mode == ADDR_SCOPE_PRIORITISED_IPV4) { return Inet4Address.getLocalHost(); } else { return Inet6Address.getLocalHost(); } } catch (UnknownHostException e) { LOGGER.error("Local host was unknown.", e); } return null; // XXX: What can we do here?? } /** * Get an InetSocketAddress from the String format "<Address>:<Port>", or * "<Address>". * * @param addressPortStr String for Address and Port. Enclose with "[" and * "]" for IPv6 addresses. * @param defaultPort defaultPort when port is not specified in * addressPortStr * @return InetSocketAddress * @throws UnknownHostException */ public static InetSocketAddress getInetSocketAddress(String addressPortStr, int defaultPort) throws UnknownHostException { if (addressPortStr == null || addressPortStr.isEmpty()) { return null; } String addressStr; int port; if (addressPortStr.charAt(0) == '[') { // [2001:1::1]:1234 or [2001:1::1] int i = addressPortStr.indexOf(']'); if (i <= 0) { return null; } addressStr = addressPortStr.substring(1, i); if (addressPortStr.length() > i + 2 && addressPortStr.charAt(i + 1) == ':') { // [2001:1::1]:1234 port = Integer.parseInt(addressPortStr.substring(i + 2)); } else if (addressPortStr.length() == i + 1) { // [2001:1::1] (is it legitimate??) port = defaultPort; } else { return null; } } else if (addressPortStr.contains(":")) { int i = addressPortStr.lastIndexOf(':'); if (addressPortStr.indexOf(':') == i) { // www.fqdn.com:1234 or 192.168.1.1:1234 addressStr = addressPortStr.substring(0, i); port = Integer.parseInt(addressPortStr.substring(i + 1)); } else { // IPv6 Address 2001:1::1 (at least including two ':') addressStr = addressPortStr; port = defaultPort; } } else { // www.fqdn.com or 192.168.1.1 addressStr = addressPortStr; port = defaultPort; } if (addressStr == null || port < 0) { return null; } return new InetSocketAddress(addressStr, port); } private static class ClassifiedAddresses { static ClassifiedAddresses getClassifiedAddresses() { ClassifiedAddresses result = new ClassifiedAddresses(); Enumeration eNetIf = null; try { eNetIf = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e) { LOGGER.error("Couldn't get network interfaces.", e); } if (eNetIf == null) { return result; } while (eNetIf.hasMoreElements()) { NetworkInterface netIf = (NetworkInterface) eNetIf.nextElement(); Enumeration eInetAddr = netIf.getInetAddresses(); while (eInetAddr.hasMoreElements()) { InetAddress inetAddr = (InetAddress) eInetAddr.nextElement(); if (inetAddr instanceof Inet4Address) { if (inetAddr.isLinkLocalAddress()) { result.linkLocalIPv4.add(inetAddr); } else if (inetAddr.isSiteLocalAddress()) { result.siteLocalIPv4.add(inetAddr); } else if (!inetAddr.isAnyLocalAddress() && !inetAddr.isMulticastAddress()) { result.globalIPv4.add(inetAddr); } } else if (inetAddr instanceof Inet6Address) { if (inetAddr.isLinkLocalAddress()) { result.linkLocalIPv6.add(inetAddr); } else if (inetAddr.isSiteLocalAddress()) { result.siteLocalIPv6.add(inetAddr); } else if (!inetAddr.isAnyLocalAddress() && !inetAddr.isMulticastAddress()) { result.globalIPv6.add(inetAddr); } } } } return result; } final public LinkedList<InetAddress> globalIPv4 = new LinkedList<>(); final public LinkedList<InetAddress> globalIPv6 = new LinkedList<>(); final public LinkedList<InetAddress> siteLocalIPv4 = new LinkedList<>(); final public LinkedList<InetAddress> siteLocalIPv6 = new LinkedList<>(); final public LinkedList<InetAddress> linkLocalIPv4 = new LinkedList<>(); final public LinkedList<InetAddress> linkLocalIPv6 = new LinkedList<>(); private ClassifiedAddresses() { } } }