mirror of https://github.com/apache/cloudstack.git
1780 lines
64 KiB
Java
1780 lines
64 KiB
Java
//
|
|
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
//
|
|
|
|
package com.cloud.utils.net;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.math.BigInteger;
|
|
import java.net.Inet4Address;
|
|
import java.net.Inet6Address;
|
|
import java.net.InetAddress;
|
|
import java.net.InterfaceAddress;
|
|
import java.net.NetworkInterface;
|
|
import java.net.SocketException;
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
import java.net.UnknownHostException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Formatter;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import java.util.Set;
|
|
import java.util.SortedSet;
|
|
import java.util.TreeSet;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
import org.apache.commons.lang.SystemUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.net.util.SubnetUtils;
|
|
import org.apache.commons.validator.routines.InetAddressValidator;
|
|
import org.apache.commons.validator.routines.RegexValidator;
|
|
import org.apache.log4j.Logger;
|
|
|
|
import com.cloud.utils.IteratorUtil;
|
|
import com.cloud.utils.Pair;
|
|
import com.cloud.utils.exception.CloudRuntimeException;
|
|
import com.cloud.utils.script.Script;
|
|
import com.googlecode.ipv6.IPv6Address;
|
|
import com.googlecode.ipv6.IPv6AddressRange;
|
|
import com.googlecode.ipv6.IPv6Network;
|
|
|
|
public class NetUtils {
|
|
protected final static Logger s_logger = Logger.getLogger(NetUtils.class);
|
|
|
|
private static final int MAX_CIDR = 32;
|
|
private static final int RFC_3021_31_BIT_CIDR = 31;
|
|
|
|
public final static int HTTP_PORT = 80;
|
|
public final static int HTTPS_PORT = 443;
|
|
public final static int VPN_PORT = 500;
|
|
public final static int VPN_NATT_PORT = 4500;
|
|
public final static int VPN_L2TP_PORT = 1701;
|
|
public final static int HAPROXY_STATS_PORT = 8081;
|
|
|
|
public final static String UDP_PROTO = "udp";
|
|
public final static String TCP_PROTO = "tcp";
|
|
public final static String ANY_PROTO = "any";
|
|
public final static String ICMP_PROTO = "icmp";
|
|
public static final String ICMP6_PROTO = "icmp6";
|
|
public final static String ALL_PROTO = "all";
|
|
public final static String HTTP_PROTO = "http";
|
|
public final static String HTTPS_PROTO = "https";
|
|
public final static String SSL_PROTO = "ssl";
|
|
|
|
public final static String ALL_IP4_CIDRS = "0.0.0.0/0";
|
|
public final static String ALL_IP6_CIDRS = "::/0";
|
|
public final static int PORT_RANGE_MIN = 0;
|
|
public final static int PORT_RANGE_MAX = 65535;
|
|
|
|
public final static int DEFAULT_AUTOSCALE_EXPUNGE_VM_GRACE_PERIOD = 2 * 60; // Grace period before Vm is expunged
|
|
public final static int DEFAULT_AUTOSCALE_POLICY_INTERVAL_TIME = 30;
|
|
public final static int DEFAULT_AUTOSCALE_POLICY_QUIET_TIME = 5 * 60;
|
|
private final static Random s_rand = new Random(System.currentTimeMillis());
|
|
private final static long prefix = 0x1e;
|
|
|
|
// RFC4291 IPv6 EUI-64
|
|
public final static int IPV6_EUI64_11TH_BYTE = -1;
|
|
public final static int IPV6_EUI64_12TH_BYTE = -2;
|
|
|
|
public static String extractHost(String uri) throws URISyntaxException {
|
|
return (new URI(uri)).getHost();
|
|
}
|
|
|
|
public enum InternetProtocol {
|
|
IPv4, IPv6, DualStack;
|
|
|
|
public static InternetProtocol fromValue(String protocol) {
|
|
if (StringUtils.isBlank(protocol)) {
|
|
return null;
|
|
} else if (protocol.equalsIgnoreCase("IPv4")) {
|
|
return IPv4;
|
|
} else if (protocol.equalsIgnoreCase("IPv6")) {
|
|
return IPv6;
|
|
} else if (protocol.equalsIgnoreCase("DualStack")) {
|
|
return DualStack;
|
|
}
|
|
throw new IllegalArgumentException("Unexpected Internet Protocol : " + protocol);
|
|
}
|
|
|
|
public static boolean isIpv6EnabledProtocol(InternetProtocol protocol) {
|
|
return IPv6.equals(protocol) || DualStack.equals(protocol);
|
|
}
|
|
}
|
|
|
|
public static long createSequenceBasedMacAddress(final long macAddress, long globalConfig) {
|
|
/*
|
|
Logic for generating MAC address:
|
|
Mac = B1:B2:B3:B4:B5:B6 (Bx is a byte).
|
|
B1 -> Presently controlled by prefix variable. The value should be such that the MAC is local and unicast.
|
|
B2 -> This will be configurable for each deployment/installation. Controlled by the global config MACIdentifier
|
|
B3 -> A randomly generated number between 0 - 255
|
|
B4,5,6 -> These bytes are based on the unique DB identifier associated with the IP address for which MAC is generated (refer to mac_address field in user_ip_address table).
|
|
*/
|
|
|
|
return macAddress | prefix<<40 | globalConfig << 32 & 0x00ff00000000l | (long)s_rand.nextInt(255) << 24;
|
|
}
|
|
|
|
public static String getHostName() {
|
|
try {
|
|
final InetAddress localAddr = InetAddress.getLocalHost();
|
|
if (localAddr != null) {
|
|
return localAddr.getHostName();
|
|
}
|
|
} catch (final UnknownHostException e) {
|
|
s_logger.warn("UnknownHostException when trying to get host name. ", e);
|
|
}
|
|
return "localhost";
|
|
}
|
|
|
|
public static String getCanonicalHostName() {
|
|
try {
|
|
InetAddress localAddr = InetAddress.getLocalHost();
|
|
if (localAddr != null) {
|
|
return localAddr.getCanonicalHostName();
|
|
}
|
|
} catch (UnknownHostException e) {
|
|
s_logger.warn("UnknownHostException when trying to get canonical host name. ", e);
|
|
}
|
|
return "localhost";
|
|
}
|
|
|
|
public static InetAddress getLocalInetAddress() {
|
|
try {
|
|
return InetAddress.getLocalHost();
|
|
} catch (final UnknownHostException e) {
|
|
s_logger.warn("UnknownHostException in getLocalInetAddress().", e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static String resolveToIp(final String host) {
|
|
try {
|
|
final InetAddress addr = InetAddress.getByName(host);
|
|
return addr.getHostAddress();
|
|
} catch (final UnknownHostException e) {
|
|
s_logger.warn("Unable to resolve " + host + " to IP due to UnknownHostException");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static InetAddress[] getAllLocalInetAddresses() {
|
|
final List<InetAddress> addrList = new ArrayList<InetAddress>();
|
|
try {
|
|
for (final NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) {
|
|
if (ifc.isUp() && !ifc.isVirtual()) {
|
|
for (final InetAddress addr : IteratorUtil.enumerationAsIterable(ifc.getInetAddresses())) {
|
|
addrList.add(addr);
|
|
}
|
|
}
|
|
}
|
|
} catch (final SocketException e) {
|
|
s_logger.warn("SocketException in getAllLocalInetAddresses().", e);
|
|
}
|
|
|
|
final InetAddress[] addrs = new InetAddress[addrList.size()];
|
|
if (addrList.size() > 0) {
|
|
System.arraycopy(addrList.toArray(), 0, addrs, 0, addrList.size());
|
|
}
|
|
return addrs;
|
|
}
|
|
|
|
public static String[] getLocalCidrs() {
|
|
final String defaultHostIp = getDefaultHostIp();
|
|
|
|
final List<String> cidrList = new ArrayList<String>();
|
|
try {
|
|
for (final NetworkInterface ifc : IteratorUtil.enumerationAsIterable(NetworkInterface.getNetworkInterfaces())) {
|
|
if (ifc.isUp() && !ifc.isVirtual() && !ifc.isLoopback()) {
|
|
for (final InterfaceAddress address : ifc.getInterfaceAddresses()) {
|
|
final InetAddress addr = address.getAddress();
|
|
final int prefixLength = address.getNetworkPrefixLength();
|
|
if (prefixLength < MAX_CIDR && prefixLength > 0) {
|
|
final String ip = addr.getHostAddress();
|
|
if (ip.equalsIgnoreCase(defaultHostIp)) {
|
|
cidrList.add(ipAndNetMaskToCidr(ip, getCidrNetmask(prefixLength)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (final SocketException e) {
|
|
s_logger.warn("UnknownHostException in getLocalCidrs().", e);
|
|
}
|
|
|
|
return cidrList.toArray(new String[0]);
|
|
}
|
|
|
|
public static String getDefaultHostIp() {
|
|
if (SystemUtils.IS_OS_WINDOWS) {
|
|
final Pattern pattern = Pattern.compile("\\s*0.0.0.0\\s*0.0.0.0\\s*(\\S*)\\s*(\\S*)\\s*");
|
|
try {
|
|
final Process result = Runtime.getRuntime().exec("route print -4");
|
|
final BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
|
|
|
|
String line = output.readLine();
|
|
while (line != null) {
|
|
final Matcher matcher = pattern.matcher(line);
|
|
if (matcher.find()) {
|
|
return matcher.group(2);
|
|
}
|
|
line = output.readLine();
|
|
}
|
|
} catch (final IOException e) {
|
|
s_logger.debug("Caught IOException", e);
|
|
}
|
|
return null;
|
|
} else {
|
|
NetworkInterface nic = null;
|
|
final String pubNic = getDefaultEthDevice();
|
|
|
|
if (pubNic == null) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
nic = NetworkInterface.getByName(pubNic);
|
|
} catch (final SocketException e) {
|
|
return null;
|
|
}
|
|
|
|
String[] info = null;
|
|
try {
|
|
info = NetUtils.getNetworkParams(nic);
|
|
} catch (final NullPointerException ignored) {
|
|
s_logger.debug("Caught NullPointerException when trying to getDefaultHostIp");
|
|
}
|
|
if (info != null) {
|
|
return info[0];
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static List<String> getAllDefaultNicIps() {
|
|
final List<String> addrs = new ArrayList<>();
|
|
final String pubNic = getDefaultEthDevice();
|
|
|
|
if (pubNic == null) {
|
|
return addrs;
|
|
}
|
|
|
|
NetworkInterface nic = null;
|
|
try {
|
|
nic = NetworkInterface.getByName(pubNic);
|
|
} catch (final SocketException e) {
|
|
return addrs;
|
|
}
|
|
|
|
for (InterfaceAddress address : nic.getInterfaceAddresses()) {
|
|
addrs.add(address.getAddress().getHostAddress().split("%")[0]);
|
|
}
|
|
return addrs;
|
|
}
|
|
|
|
public static String getDefaultEthDevice() {
|
|
if (SystemUtils.IS_OS_MAC) {
|
|
final String defDev = Script.runSimpleBashScript("/sbin/route -n get default 2> /dev/null | grep interface | awk '{print $2}'");
|
|
return defDev;
|
|
}
|
|
return Script.runSimpleBashScript("ip route show default 0.0.0.0/0 | head -1 | awk '{print $5}'");
|
|
}
|
|
|
|
public static String getLocalIPString() {
|
|
final InetAddress addr = getLocalInetAddress();
|
|
if (addr != null) {
|
|
return addr.getHostAddress();
|
|
}
|
|
|
|
return "127.0.0.1";
|
|
}
|
|
|
|
public static boolean isLocalAddress(final InetAddress addr) {
|
|
final InetAddress[] addrs = getAllLocalInetAddresses();
|
|
|
|
if (addrs != null) {
|
|
for (final InetAddress self : addrs) {
|
|
if (self.equals(addr)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static boolean isLocalAddress(final String strAddress) {
|
|
try {
|
|
InetAddress addr = InetAddress.getByName(strAddress);
|
|
return isLocalAddress(addr);
|
|
} catch (final UnknownHostException e) {
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static String getMacAddress(final InetAddress address) {
|
|
final StringBuffer sb = new StringBuffer();
|
|
final Formatter formatter = new Formatter(sb);
|
|
try {
|
|
final NetworkInterface ni = NetworkInterface.getByInetAddress(address);
|
|
final byte[] mac = ni.getHardwareAddress();
|
|
|
|
for (int i = 0; i < mac.length; i++) {
|
|
formatter.format("%02X%s", mac[i], i < mac.length - 1 ? ":" : "");
|
|
}
|
|
} catch (final SocketException e) {
|
|
s_logger.error("SocketException when trying to retrieve MAC address", e);
|
|
} finally {
|
|
formatter.close();
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
/**
|
|
* This method will fail in case we have a 31 Bit prefix network
|
|
* See RFC 3021.
|
|
*
|
|
* In order to avoid calling this method, please check the <code>NetUtils.is31PrefixCidr(cidr)</code> first.
|
|
*/
|
|
public static boolean ipRangesOverlap(final String startIp1, final String endIp1, final String startIp2, final String endIp2) {
|
|
final long startIp1Long = ip2Long(startIp1);
|
|
long endIp1Long = startIp1Long;
|
|
if (endIp1 != null) {
|
|
endIp1Long = ip2Long(endIp1);
|
|
}
|
|
final long startIp2Long = ip2Long(startIp2);
|
|
long endIp2Long = startIp2Long;
|
|
if (endIp2 != null) {
|
|
endIp2Long = ip2Long(endIp2);
|
|
}
|
|
|
|
if (startIp1Long == startIp2Long || startIp1Long == endIp2Long || endIp1Long == startIp2Long || endIp1Long == endIp2Long) {
|
|
return true;
|
|
} else if (startIp1Long > startIp2Long && startIp1Long < endIp2Long) {
|
|
return true;
|
|
} else if (endIp1Long > startIp2Long && endIp1Long < endIp2Long) {
|
|
return true;
|
|
} else if (startIp2Long > startIp1Long && startIp2Long < endIp1Long) {
|
|
return true;
|
|
} else if (endIp2Long > startIp1Long && endIp2Long < endIp1Long) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static long ip2Long(final String ip) {
|
|
final String[] tokens = ip.split("[.]");
|
|
assert tokens.length == 4;
|
|
long result = 0;
|
|
for (int i = 0; i < tokens.length; i++) {
|
|
try {
|
|
result = result << 8 | Integer.parseInt(tokens[i]);
|
|
} catch (final NumberFormatException e) {
|
|
throw new RuntimeException("Incorrect number", e);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static String long2Ip(final long ip) {
|
|
final StringBuilder result = new StringBuilder(15);
|
|
result.append(ip >> 24 & 0xff).append(".");
|
|
result.append(ip >> 16 & 0xff).append(".");
|
|
result.append(ip >> 8 & 0xff).append(".");
|
|
result.append(ip & 0xff);
|
|
|
|
return result.toString();
|
|
}
|
|
|
|
public static long mac2Long(final String macAddress) {
|
|
final String[] tokens = macAddress.split(":");
|
|
assert tokens.length == 6;
|
|
long result = 0;
|
|
for (int i = 0; i < tokens.length; i++) {
|
|
result = result << 8;
|
|
result |= Integer.parseInt(tokens[i], 16);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static String[] getNicParams(final String nicName) {
|
|
try {
|
|
final NetworkInterface nic = NetworkInterface.getByName(nicName);
|
|
return getNetworkParams(nic);
|
|
} catch (final SocketException e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static String[] getNetworkParams(NetworkInterface nic) {
|
|
s_logger.debug(String.format("Retrieving network params of NIC [%s].", nic));
|
|
|
|
s_logger.trace(String.format("Retrieving all NIC [%s] addresses.", nic));
|
|
List<InterfaceAddress> addrs = nic.getInterfaceAddresses();
|
|
if (CollectionUtils.isEmpty(addrs)) {
|
|
s_logger.debug(String.format("NIC [%s] has no addresses, returning null.", nic));
|
|
return null;
|
|
}
|
|
|
|
String addrsToString = Arrays.toString(addrs.toArray());
|
|
s_logger.trace(String.format("Found [%s] as NIC [%s] addresses. Reversing the list order because it has reverse order in \"ip addr show\".",
|
|
addrsToString, nic));
|
|
|
|
Collections.reverse(addrs);
|
|
InterfaceAddress addr = null;
|
|
|
|
s_logger.trace(String.format("Iterating through the NIC [%s] addresses [%s] to find a valid address.", nic, addrsToString));
|
|
for (InterfaceAddress iaddr : addrs) {
|
|
InetAddress inet = iaddr.getAddress();
|
|
s_logger.trace(String.format("Validating address [%s].", inet));
|
|
if (!inet.isLinkLocalAddress() && !inet.isLoopbackAddress() && !inet.isMulticastAddress() && inet.getAddress().length == 4) {
|
|
addr = iaddr;
|
|
break;
|
|
}
|
|
s_logger.trace(String.format("Address [%s] is link local [%s], loopback [%s], multicast [%s], or does not have 4 octets [%s]; therefore we will not retrieve its" +
|
|
" interface params.", inet, inet.isLinkLocalAddress(), inet.isLoopbackAddress(), inet.isMulticastAddress(), inet.getAddress().length));
|
|
}
|
|
if (addr == null) {
|
|
s_logger.debug(String.format("Could not find a valid address in NIC [%s], returning null.", nic));
|
|
return null;
|
|
}
|
|
|
|
s_logger.debug(String.format("Retrieving params of address [%s] of NIC [%s].", addr, nic));
|
|
|
|
String[] result = new String[3];
|
|
result[0] = addr.getAddress().getHostAddress();
|
|
|
|
try {
|
|
final byte[] mac = nic.getHardwareAddress();
|
|
result[1] = byte2Mac(mac);
|
|
} catch (final SocketException e) {
|
|
s_logger.warn(String.format("Unable to get NIC's [%s] MAC address due to [%s].", nic, e.getMessage()), e);
|
|
}
|
|
|
|
result[2] = prefix2Netmask(addr.getNetworkPrefixLength());
|
|
return result;
|
|
}
|
|
|
|
public static String prefix2Netmask(final short prefix) {
|
|
long addr = 0;
|
|
for (int i = 0; i < prefix; i++) {
|
|
addr = addr | 1 << 31 - i;
|
|
}
|
|
|
|
return long2Ip(addr);
|
|
}
|
|
|
|
public static String byte2Mac(final byte[] m) {
|
|
final StringBuilder result = new StringBuilder(17);
|
|
final Formatter formatter = new Formatter(result);
|
|
formatter.format("%02x:%02x:%02x:%02x:%02x:%02x", m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
formatter.close();
|
|
return result.toString();
|
|
}
|
|
|
|
public static String long2Mac(final long macAddress) {
|
|
final StringBuilder result = new StringBuilder(17);
|
|
try (Formatter formatter = new Formatter(result)) {
|
|
formatter.format("%02x:%02x:%02x:%02x:%02x:%02x",
|
|
macAddress >> 40 & 0xff, macAddress >> 32 & 0xff,
|
|
macAddress >> 24 & 0xff, macAddress >> 16 & 0xff,
|
|
macAddress >> 8 & 0xff, macAddress & 0xff);
|
|
}
|
|
return result.toString();
|
|
}
|
|
|
|
public static boolean isSiteLocalAddress(final String ipAddress) {
|
|
try {
|
|
final InetAddress ip = InetAddress.getByName(ipAddress);
|
|
if (ip != null) {
|
|
return ip.isSiteLocalAddress();
|
|
}
|
|
} catch (UnknownHostException e) {}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static boolean validIpRange(final String startIP, final String endIP) {
|
|
if (endIP == null || endIP.isEmpty()) {
|
|
return true;
|
|
}
|
|
|
|
final long startIPLong = NetUtils.ip2Long(startIP);
|
|
final long endIPLong = NetUtils.ip2Long(endIP);
|
|
return startIPLong <= endIPLong;
|
|
}
|
|
|
|
public static boolean isValidIp4(final String ip) {
|
|
if (ip == null)
|
|
return false;
|
|
|
|
final InetAddressValidator validator = InetAddressValidator.getInstance();
|
|
return validator.isValidInet4Address(ip);
|
|
}
|
|
|
|
/**
|
|
* Returns true if the given IPv4 address is in the specific Ipv4 range
|
|
*/
|
|
public static boolean isIpInRange(final String ipInRange, final String startIP, final String endIP) {
|
|
if (ipInRange == null || !validIpRange(startIP, endIP))
|
|
return false;
|
|
|
|
final long ipInRangeLong = NetUtils.ip2Long(ipInRange);
|
|
final long startIPLong = NetUtils.ip2Long(startIP);
|
|
final long endIPLong = NetUtils.ip2Long(endIP);
|
|
|
|
return startIPLong <= ipInRangeLong && ipInRangeLong <= endIPLong;
|
|
}
|
|
|
|
public static boolean is31PrefixCidr(final String cidr) {
|
|
final boolean isValidCird = isValidIp4Cidr(cidr);
|
|
if (isValidCird) {
|
|
final String[] cidrPair = cidr.split("\\/");
|
|
final String cidrSize = cidrPair[1];
|
|
|
|
final int cidrSizeNum = Integer.parseInt(cidrSize);
|
|
if (cidrSizeNum == RFC_3021_31_BIT_CIDR) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static boolean isValidIp4Cidr(final String cidr) {
|
|
if (cidr == null || cidr.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
final String[] cidrPair = cidr.split("\\/");
|
|
if (cidrPair.length != 2) {
|
|
return false;
|
|
}
|
|
final String cidrAddress = cidrPair[0];
|
|
final String cidrSize = cidrPair[1];
|
|
if (!isValidIp4(cidrAddress)) {
|
|
return false;
|
|
}
|
|
int cidrSizeNum = -1;
|
|
|
|
try {
|
|
cidrSizeNum = Integer.parseInt(cidrSize);
|
|
} catch (final Exception e) {
|
|
return false;
|
|
}
|
|
|
|
if (cidrSizeNum < 0 || cidrSizeNum > MAX_CIDR) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static boolean isValidIp4Netmask(final String netmask) {
|
|
if (!isValidIp4(netmask)) {
|
|
return false;
|
|
}
|
|
|
|
final long ip = ip2Long(netmask);
|
|
int count = 0;
|
|
boolean finished = false;
|
|
for (int i = 31; i >= 0; i--) {
|
|
if ((ip >> i & 0x1) == 0) {
|
|
finished = true;
|
|
} else {
|
|
if (finished) {
|
|
return false;
|
|
}
|
|
count += 1;
|
|
}
|
|
}
|
|
|
|
if (count == 0) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static String getCidrFromGatewayAndNetmask(final String gatewayStr, final String netmaskStr) {
|
|
final long netmask = ip2Long(netmaskStr);
|
|
final long gateway = ip2Long(gatewayStr);
|
|
final long firstPart = gateway & netmask;
|
|
final long size = getCidrSize(netmaskStr);
|
|
return long2Ip(firstPart) + "/" + size;
|
|
}
|
|
|
|
public static String[] getIpRangeFromCidr(final String cidr, final long size) {
|
|
assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
|
|
final String[] result = new String[2];
|
|
final long ip = ip2Long(cidr);
|
|
final long startNetMask = ip2Long(getCidrNetmask(size));
|
|
final long start = (ip & startNetMask) + 1;
|
|
long end = start;
|
|
|
|
end = end >> MAX_CIDR - size;
|
|
|
|
end++;
|
|
end = (end << MAX_CIDR - size) - 2;
|
|
|
|
result[0] = long2Ip(start);
|
|
result[1] = long2Ip(end);
|
|
|
|
return result;
|
|
}
|
|
|
|
public static Set<Long> getAllIpsFromCidr(final String cidr, final long size, final Set<Long> usedIps, int maxIps) {
|
|
assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
|
|
final Set<Long> result = new TreeSet<Long>();
|
|
final long ip = ip2Long(cidr);
|
|
final long startNetMask = ip2Long(getCidrNetmask(size));
|
|
long start = (ip & startNetMask) + 1;
|
|
long end = start;
|
|
|
|
end = end >> MAX_CIDR - size;
|
|
|
|
end++;
|
|
end = (end << MAX_CIDR - size) - 2;
|
|
while (start <= end && (maxIps == -1 || result.size() < maxIps)) {
|
|
if (!usedIps.contains(start)) {
|
|
result.add(start);
|
|
}
|
|
start++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Given a cidr, this method returns an ip address within the range but
|
|
* is not in the avoid list.
|
|
*
|
|
* @param startIp ip that the cidr starts with
|
|
* @param size size of the cidr
|
|
* @param avoid set of ips to avoid
|
|
* @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one.
|
|
*/
|
|
public static long getRandomIpFromCidr(final String startIp, final int size, final SortedSet<Long> avoid) {
|
|
return getRandomIpFromCidr(ip2Long(startIp), size, avoid);
|
|
|
|
}
|
|
|
|
/**
|
|
* Given a cidr, this method returns an ip address within the range but
|
|
* is not in the avoid list.
|
|
* Note: the gateway address has to be specified in the avoid list
|
|
*
|
|
* @param cidr ip that the cidr starts with
|
|
* @param size size of the cidr
|
|
* @param avoid set of ips to avoid
|
|
* @return ip that is within the cidr range but not in the avoid set. -1 if unable to find one.
|
|
*/
|
|
public static long getRandomIpFromCidr(final long cidr, final int size, final SortedSet<Long> avoid) {
|
|
assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
|
|
|
|
final long startNetMask = ip2Long(getCidrNetmask(size));
|
|
final long startIp = (cidr & startNetMask) + 1; //exclude the first ip since it isnt valid, e.g., 192.168.10.0
|
|
int range = 1 << MAX_CIDR - size; //e.g., /24 = 2^8 = 256
|
|
range = range - 1; //exclude end of the range since that is the broadcast address, e.g., 192.168.10.255
|
|
|
|
if (avoid.size() >= range) {
|
|
return -1;
|
|
}
|
|
|
|
//Reduce the range by the size of the avoid set
|
|
//e.g., cidr = 192.168.10.0, size = /24, avoid = 192.168.10.1, 192.168.10.20, 192.168.10.254
|
|
// range = 2^8 - 1 - 3 = 252
|
|
range = range - avoid.size();
|
|
final int next = s_rand.nextInt(range); //note: nextInt excludes last value
|
|
long ip = startIp + next;
|
|
for (final Long avoidable : avoid) {
|
|
if (ip >= avoidable) {
|
|
ip++;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ip;
|
|
}
|
|
|
|
public static String getIpRangeStartIpFromCidr(final String cidr, final long size) {
|
|
final long ip = ip2Long(cidr);
|
|
final long startNetMask = ip2Long(getCidrNetmask(size));
|
|
final long start = (ip & startNetMask) + 1;
|
|
return long2Ip(start);
|
|
}
|
|
|
|
public static String getIpRangeEndIpFromCidr(final String cidr, final long size) {
|
|
final long ip = ip2Long(cidr);
|
|
final long startNetMask = ip2Long(getCidrNetmask(size));
|
|
final long start = (ip & startNetMask) + 1;
|
|
long end = start;
|
|
end = end >> MAX_CIDR - size;
|
|
|
|
end++;
|
|
end = (end << MAX_CIDR - size) - 2;
|
|
return long2Ip(end);
|
|
}
|
|
|
|
public static boolean sameSubnet(final String ip1, final String ip2, final String netmask) {
|
|
if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) {
|
|
return true;
|
|
}
|
|
final String subnet1 = NetUtils.getSubNet(ip1, netmask);
|
|
final String subnet2 = NetUtils.getSubNet(ip2, netmask);
|
|
|
|
return subnet1.equals(subnet2);
|
|
}
|
|
|
|
public static boolean sameSubnetCIDR(final String ip1, final String ip2, final long cidrSize) {
|
|
if (ip1 == null || ip1.isEmpty() || ip2 == null || ip2.isEmpty()) {
|
|
return true;
|
|
}
|
|
final String subnet1 = NetUtils.getCidrSubNet(ip1, cidrSize);
|
|
final String subnet2 = NetUtils.getCidrSubNet(ip2, cidrSize);
|
|
|
|
return subnet1.equals(subnet2);
|
|
}
|
|
|
|
public static String getSubNet(final String ip, final String netmask) {
|
|
final long ipAddr = ip2Long(ip);
|
|
final long subnet = ip2Long(netmask);
|
|
final long result = ipAddr & subnet;
|
|
return long2Ip(result);
|
|
}
|
|
|
|
public static String getCidrSubNet(final String ip, final long cidrSize) {
|
|
final long numericNetmask = netMaskFromCidr(cidrSize);
|
|
final String netmask = NetUtils.long2Ip(numericNetmask);
|
|
return getSubNet(ip, netmask);
|
|
}
|
|
|
|
/**
|
|
* @param cidrSize
|
|
* @return
|
|
*/
|
|
static long netMaskFromCidr(final long cidrSize) {
|
|
return ((long)0xffffffff) >> MAX_CIDR - cidrSize << MAX_CIDR - cidrSize;
|
|
}
|
|
|
|
public static String ipAndNetMaskToCidr(final String ip, final String netmask) {
|
|
if (!isValidIp4(ip)) {
|
|
return null;
|
|
}
|
|
|
|
if (!isValidIp4Netmask(netmask)) {
|
|
return null;
|
|
}
|
|
|
|
final long ipAddr = ip2Long(ip);
|
|
final long subnet = ip2Long(netmask);
|
|
final long result = ipAddr & subnet;
|
|
int bits = subnet == 0 ? 0 : 1;
|
|
long subnet2 = subnet;
|
|
while ((subnet2 = subnet2 >> 1 & subnet) != 0) {
|
|
bits++;
|
|
}
|
|
|
|
return long2Ip(result) + "/" + Integer.toString(bits);
|
|
}
|
|
|
|
public static String[] ipAndNetMaskToRange(final String ip, final String netmask) {
|
|
final long ipAddr = ip2Long(ip);
|
|
long subnet = ip2Long(netmask);
|
|
final long start = (ipAddr & subnet) + 1;
|
|
long end = start;
|
|
int bits = subnet == 0 ? 0 : 1;
|
|
while ((subnet = subnet >> 1 & subnet) != 0) {
|
|
bits++;
|
|
}
|
|
end = end >> MAX_CIDR - bits;
|
|
|
|
end++;
|
|
end = (end << MAX_CIDR - bits) - 2;
|
|
|
|
return new String[] {long2Ip(start), long2Ip(end)};
|
|
|
|
}
|
|
|
|
public static Pair<String, Integer> getCidr(final String cidr) {
|
|
final String[] tokens = cidr.split("/");
|
|
return new Pair<String, Integer>(tokens[0], Integer.parseInt(tokens[1]));
|
|
}
|
|
|
|
public static enum SupersetOrSubset {
|
|
isSuperset, isSubset, neitherSubetNorSuperset, sameSubnet, errorInCidrFormat
|
|
}
|
|
|
|
public static SupersetOrSubset isNetowrkASubsetOrSupersetOfNetworkB(final String cidrA, final String cidrB) {
|
|
if (!areCidrsNotEmpty(cidrA, cidrB)) {
|
|
return SupersetOrSubset.errorInCidrFormat;
|
|
}
|
|
final Long[] cidrALong = cidrToLong(cidrA);
|
|
final Long[] cidrBLong = cidrToLong(cidrB);
|
|
long shift = 0;
|
|
|
|
if (cidrALong[1] >= cidrBLong[1]) {
|
|
shift = MAX_CIDR - cidrBLong[1];
|
|
} else {
|
|
shift = MAX_CIDR - cidrALong[1];
|
|
}
|
|
final long result = (cidrALong[0] >> shift) - (cidrBLong[0] >> shift);
|
|
if (result == 0) {
|
|
if (cidrALong[1] < cidrBLong[1]) {
|
|
//this implies cidrA is super set of cidrB
|
|
return SupersetOrSubset.isSuperset;
|
|
} else if (cidrALong[1].equals(cidrBLong[1])) {
|
|
//this implies both the cidrs are equal
|
|
return SupersetOrSubset.sameSubnet;
|
|
}
|
|
// implies cidrA is subset of cidrB
|
|
return SupersetOrSubset.isSubset;
|
|
}
|
|
//this implies no overlap.
|
|
return SupersetOrSubset.neitherSubetNorSuperset;
|
|
}
|
|
|
|
public static boolean isNetworkAWithinNetworkB(final String cidrA, final String cidrB) {
|
|
if (!areCidrsNotEmpty(cidrA, cidrB)) {
|
|
return false;
|
|
}
|
|
Long[] cidrALong = cidrToLong(cidrA);
|
|
Long[] cidrBLong = cidrToLong(cidrB);
|
|
|
|
long shift = MAX_CIDR - cidrBLong[1];
|
|
return (cidrALong[0] >> shift == cidrBLong[0] >> shift) && (cidrALong[1] >= cidrBLong[1]);
|
|
}
|
|
|
|
static boolean areCidrsNotEmpty(String cidrA, String cidrB) {
|
|
return StringUtils.isNoneEmpty(cidrA, cidrB);
|
|
}
|
|
|
|
public static Long[] cidrToLong(final String cidr) {
|
|
if (cidr == null || cidr.isEmpty()) {
|
|
throw new CloudRuntimeException("empty cidr can not be converted to longs");
|
|
}
|
|
final String[] cidrPair = cidr.split("\\/");
|
|
if (cidrPair.length != 2) {
|
|
throw new CloudRuntimeException("cidr is not formatted correctly: "+ cidr);
|
|
}
|
|
final String cidrAddress = cidrPair[0];
|
|
final String cidrSize = cidrPair[1];
|
|
if (!isValidIp4(cidrAddress)) {
|
|
throw new CloudRuntimeException("cidr is not valid in ip space" + cidr);
|
|
}
|
|
long cidrSizeNum = getCidrSizeFromString(cidrSize);
|
|
final long numericNetmask = netMaskFromCidr(cidrSizeNum);
|
|
final long ipAddr = ip2Long(cidrAddress);
|
|
final Long[] cidrlong = {ipAddr & numericNetmask, cidrSizeNum};
|
|
return cidrlong;
|
|
|
|
}
|
|
|
|
/**
|
|
* @param cidrSize
|
|
* @return
|
|
* @throws CloudRuntimeException
|
|
*/
|
|
static long getCidrSizeFromString(final String cidrSize) throws CloudRuntimeException {
|
|
long cidrSizeNum = -1;
|
|
|
|
try {
|
|
cidrSizeNum = Integer.parseInt(cidrSize);
|
|
} catch (final NumberFormatException e) {
|
|
throw new CloudRuntimeException("cidrsize is not a valid int: " + cidrSize, e);
|
|
}
|
|
if(cidrSizeNum > 32 || cidrSizeNum < 0) {// assuming IPv4
|
|
throw new CloudRuntimeException("cidr size out of range: " + cidrSizeNum);
|
|
}
|
|
return cidrSizeNum;
|
|
}
|
|
|
|
public static String getCidrSubNet(final String cidr) {
|
|
if (cidr == null || cidr.isEmpty()) {
|
|
return null;
|
|
}
|
|
final String[] cidrPair = cidr.split("\\/");
|
|
if (cidrPair.length != 2) {
|
|
return null;
|
|
}
|
|
final String cidrAddress = cidrPair[0];
|
|
final String cidrSize = cidrPair[1];
|
|
if (!isValidIp4(cidrAddress)) {
|
|
return null;
|
|
}
|
|
long cidrSizeNum = getCidrSizeFromString(cidrSize);
|
|
final long numericNetmask = netMaskFromCidr(cidrSizeNum);
|
|
final String netmask = NetUtils.long2Ip(numericNetmask);
|
|
return getSubNet(cidrAddress, netmask);
|
|
}
|
|
|
|
public static String getCidrNetmask(final long cidrSize) {
|
|
final long numericNetmask = netMaskFromCidr(cidrSize);
|
|
return long2Ip(numericNetmask);
|
|
}
|
|
|
|
public static String getCidrNetmask(final String cidr) {
|
|
final String[] cidrPair = cidr.split("\\/");
|
|
final long guestCidrSize = Long.parseLong(cidrPair[1]);
|
|
return getCidrNetmask(guestCidrSize);
|
|
}
|
|
|
|
public static String cidr2Netmask(final String cidr) {
|
|
final String[] tokens = cidr.split("\\/");
|
|
return getCidrNetmask(Integer.parseInt(tokens[1]));
|
|
}
|
|
|
|
public static long getCidrSize(final String netmask) {
|
|
final long ip = ip2Long(netmask);
|
|
int count = 0;
|
|
for (int i = 0; i < MAX_CIDR; i++) {
|
|
if ((ip >> i & 0x1) == 0) {
|
|
count++;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return MAX_CIDR - count;
|
|
}
|
|
|
|
public static boolean isValidPort(final int p) {
|
|
return !(p > PORT_RANGE_MAX || p < PORT_RANGE_MIN);
|
|
}
|
|
|
|
public static boolean isValidPort(final String p) {
|
|
try {
|
|
return isValidPort(Integer.parseInt(p));
|
|
} catch (final NumberFormatException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static boolean isValidProto(final String p) {
|
|
final String proto = p.toLowerCase();
|
|
return proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO);
|
|
}
|
|
|
|
public static boolean isValidSecurityGroupProto(final String p) {
|
|
final String proto = p.toLowerCase();
|
|
return proto.equals(TCP_PROTO) || proto.equals(UDP_PROTO) || proto.equals(ICMP_PROTO) || proto.equals(ALL_PROTO);
|
|
}
|
|
|
|
public static boolean isValidAlgorithm(final String p) {
|
|
final String algo = p.toLowerCase();
|
|
return algo.equals("roundrobin") || algo.equals("leastconn") || algo.equals("source");
|
|
}
|
|
|
|
public static boolean isValidAutoScaleAction(final String p) {
|
|
final String action = p.toLowerCase();
|
|
return action.equals("scaleup") || action.equals("scaledown");
|
|
}
|
|
|
|
public static String getLinkLocalNetMask() {
|
|
return "255.255.0.0";
|
|
}
|
|
|
|
public static String getLinkLocalGateway(String cidr) {
|
|
return getLinkLocalFirstAddressFromCIDR(cidr);
|
|
}
|
|
|
|
public static String getLinkLocalGateway() {
|
|
return getLinkLocalGateway(getLinkLocalCIDR());
|
|
}
|
|
|
|
public static String getLinkLocalCIDR() {
|
|
return "169.254.0.0/16";
|
|
}
|
|
|
|
public static String getLinkLocalFirstAddressFromCIDR(final String cidr) {
|
|
SubnetUtils subnetUtils = new SubnetUtils(cidr);
|
|
return subnetUtils.getInfo().getLowAddress();
|
|
}
|
|
|
|
public static String getLinkLocalAddressFromCIDR(final String cidr) {
|
|
return getLinkLocalFirstAddressFromCIDR(cidr) + "/" + cidr2Netmask(cidr);
|
|
}
|
|
|
|
public static String[] getLinkLocalIPRange(final String cidr) {
|
|
final SubnetUtils subnetUtils = new SubnetUtils(cidr);
|
|
final String[] addresses = subnetUtils.getInfo().getAllAddresses();
|
|
final String[] range = new String[2];
|
|
range[0] = addresses[1];
|
|
range[1] = subnetUtils.getInfo().getHighAddress();
|
|
|
|
return range;
|
|
}
|
|
|
|
public static String getLinkLocalIpEnd() {
|
|
final String[] cidrPair = getLinkLocalCIDR().split("\\/");
|
|
final String cidr = cidrPair[0];
|
|
|
|
return getIpRangeEndIpFromCidr(cidr, MAX_CIDR - Long.parseLong(cidrPair[1]));
|
|
}
|
|
|
|
public static String portRangeToString(final int portRange[]) {
|
|
return Integer.toString(portRange[0]) + ":" + Integer.toString(portRange[1]);
|
|
}
|
|
|
|
public static boolean verifyDomainNameLabel(final String hostName, final boolean isHostName) {
|
|
// must be between 1 and 63 characters long and may contain only the ASCII letters 'a' through 'z' (in a
|
|
// case-insensitive manner),
|
|
// the digits '0' through '9', and the hyphen ('-').
|
|
// Can not start with a hyphen and digit, and must not end with a hyphen
|
|
// If it's a host name, don't allow to start with digit
|
|
|
|
if (hostName.length() > 63 || hostName.length() < 1) {
|
|
s_logger.warn("Domain name label must be between 1 and 63 characters long");
|
|
return false;
|
|
} else if (!hostName.toLowerCase().matches("[a-z0-9-]*")) {
|
|
s_logger.warn("Domain name label may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner)");
|
|
return false;
|
|
} else if (hostName.startsWith("-") || hostName.endsWith("-")) {
|
|
s_logger.warn("Domain name label can not start with a hyphen and digit, and must not end with a hyphen");
|
|
return false;
|
|
} else if (isHostName && hostName.matches("^[0-9-].*")) {
|
|
s_logger.warn("Host name can't start with digit");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static boolean verifyDomainName(final String domainName) {
|
|
// don't allow domain name length to exceed 190 chars (190 + 63 (max host name length) = 253 = max domainName length
|
|
if (domainName.length() < 1 || domainName.length() > 190) {
|
|
s_logger.trace("Domain name must be between 1 and 190 characters long");
|
|
return false;
|
|
}
|
|
|
|
if (domainName.startsWith(".") || domainName.endsWith(".")) {
|
|
s_logger.trace("Domain name can't start or end with .");
|
|
return false;
|
|
}
|
|
|
|
final String[] domainNameLabels = domainName.split("\\.");
|
|
|
|
for (int i = 0; i < domainNameLabels.length; i++) {
|
|
if (!verifyDomainNameLabel(domainNameLabels[i], false)) {
|
|
s_logger.warn("Domain name label " + domainNameLabels[i] + " is incorrect");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static String getDhcpRange(final String cidr) {
|
|
final String[] splitResult = cidr.split("\\/");
|
|
final long size = Long.parseLong(splitResult[1]);
|
|
return NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size);
|
|
}
|
|
|
|
// Check if 2 CIDRs have exactly same IP Range
|
|
public static boolean isSameIpRange(final String cidrA, final String cidrB) {
|
|
|
|
if (!NetUtils.isValidIp4Cidr(cidrA)) {
|
|
s_logger.info("Invalid value of cidr " + cidrA);
|
|
return false;
|
|
}
|
|
if (!NetUtils.isValidIp4Cidr(cidrB)) {
|
|
s_logger.info("Invalid value of cidr " + cidrB);
|
|
return false;
|
|
}
|
|
final String[] cidrPairFirst = cidrA.split("\\/");
|
|
final String[] cidrPairSecond = cidrB.split("\\/");
|
|
|
|
final Long networkSizeFirst = Long.valueOf(cidrPairFirst[1]);
|
|
final Long networkSizeSecond = Long.valueOf(cidrPairSecond[1]);
|
|
final String ipRangeFirst[] = NetUtils.getIpRangeFromCidr(cidrPairFirst[0], networkSizeFirst);
|
|
final String ipRangeSecond[] = NetUtils.getIpRangeFromCidr(cidrPairFirst[0], networkSizeSecond);
|
|
|
|
final long startIpFirst = NetUtils.ip2Long(ipRangeFirst[0]);
|
|
final long endIpFirst = NetUtils.ip2Long(ipRangeFirst[1]);
|
|
final long startIpSecond = NetUtils.ip2Long(ipRangeSecond[0]);
|
|
final long endIpSecond = NetUtils.ip2Long(ipRangeSecond[1]);
|
|
if (startIpFirst == startIpSecond && endIpFirst == endIpSecond) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static boolean validateGuestCidr(final String cidr) {
|
|
// RFC 1918 - The Internet Assigned Numbers Authority (IANA) has reserved the
|
|
// following three blocks of the IP address space for private internets:
|
|
// 10.0.0.0 - 10.255.255.255 (10/8 prefix)
|
|
// 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
|
|
// 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
|
|
// RFC 6598 - The IETF detailed shared address space for use in ISP CGN
|
|
// deployments and NAT devices that can handle the same addresses occurring both on inbound and outbound interfaces.
|
|
// ARIN returned space to the IANA as needed for this allocation.
|
|
// The allocated address block is 100.64.0.0/10
|
|
final String[] allowedNetBlocks = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "100.64.0.0/10"};
|
|
|
|
if (!isValidIp4Cidr(cidr)) {
|
|
s_logger.warn("Cidr " + cidr + " is not valid");
|
|
return false;
|
|
}
|
|
|
|
for (String block: allowedNetBlocks) {
|
|
if (isNetworkAWithinNetworkB(cidr, block)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// not in allowedNetBlocks - return false
|
|
s_logger.warn("cidr " + cidr + " is not RFC 1918 or 6598 compliant");
|
|
return false;
|
|
}
|
|
|
|
public static boolean isValidMac(final String macAddr) {
|
|
RegexValidator mv = new RegexValidator("^(?:[0-9a-f]{1,2}([-:\\.]))(?:[0-9a-f]{1,2}\\1){4}[0-9a-f]{1,2}$", false);
|
|
return mv.isValid(macAddr);
|
|
}
|
|
|
|
public static boolean isUnicastMac(final String macAddr) {
|
|
String std = standardizeMacAddress(macAddr);
|
|
if(std == null) {
|
|
return false;
|
|
}
|
|
long stdl = mac2Long(std);
|
|
// libvirt refuses to attach a mac address that is multicast, as defined
|
|
// by the least significant bit of the first octet of the mac.
|
|
long mask = 0x1l << 40l;
|
|
return ((stdl & mask) == mask) ? false : true;
|
|
}
|
|
|
|
public static boolean verifyInstanceName(final String instanceName) {
|
|
//instance name for cloudstack vms shouldn't contain - and spaces
|
|
if (instanceName.contains("-") || instanceName.contains(" ") || instanceName.contains("+")) {
|
|
s_logger.warn("Instance name can not contain hyphen, spaces and \"+\" char");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static boolean isNetworksOverlap(final String cidrA, final String cidrB) {
|
|
try {
|
|
Long[] cidrALong = cidrToLong(cidrA);
|
|
Long[] cidrBLong = cidrToLong(cidrB);
|
|
final long shift = MAX_CIDR - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]);
|
|
return cidrALong[0] >> shift == cidrBLong[0] >> shift;
|
|
} catch (CloudRuntimeException e) {
|
|
s_logger.error(e.getLocalizedMessage(),e);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static boolean isValidS2SVpnPolicy(final String policyType, final String policys) {
|
|
if (policyType == null || policyType.isEmpty()) {
|
|
return false;
|
|
}
|
|
if (policys == null || policys.isEmpty()) {
|
|
return false;
|
|
}
|
|
for (final String policy : policys.split(",")) {
|
|
if (policy.isEmpty()) {
|
|
return false;
|
|
}
|
|
final String cipherHash = policy.split(";")[0];
|
|
if (cipherHash.isEmpty()) {
|
|
return false;
|
|
}
|
|
final String[] list = cipherHash.split("-");
|
|
if (list.length != 2) {
|
|
return false;
|
|
}
|
|
final String cipher = list[0];
|
|
final String hash = list[1];
|
|
if (!cipher.matches("3des|aes128|aes192|aes256")) {
|
|
return false;
|
|
}
|
|
if (!hash.matches("md5|sha1|sha256|sha384|sha512")) {
|
|
return false;
|
|
}
|
|
String group = null;
|
|
if (!policy.equals(cipherHash)) {
|
|
group = policy.split(";")[1];
|
|
}
|
|
if (group == null && policyType.toLowerCase().matches("ike")) {
|
|
return false; // StrongSwan requires a DH group for the IKE policy
|
|
}
|
|
if (group != null && !group.matches("modp1024|modp1536|modp2048|modp3072|modp4096|modp6144|modp8192")) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static boolean isValidCidrList(final String cidrList) {
|
|
if (StringUtils.isBlank(cidrList)) {
|
|
return false;
|
|
}
|
|
for (final String guestCidr : cidrList.split(",")) {
|
|
if (!isValidIp4Cidr(guestCidr)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static boolean validateGuestCidrList(final String guestCidrList) {
|
|
for (final String guestCidr : guestCidrList.split(",")) {
|
|
if (!validateGuestCidr(guestCidr)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static boolean validateIcmpType(final long icmpType) {
|
|
//Source - http://www.erg.abdn.ac.uk/~gorry/course/inet-pages/icmp-code.html
|
|
if (!(icmpType >= 0 && icmpType <= 255)) {
|
|
s_logger.warn("impcType is not within 0-255 range");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static boolean validateIcmpCode(final long icmpCode) {
|
|
|
|
// Reference: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml#icmp-parameters-codes-9/#table-icmp-parameters-ext-classes
|
|
if (!(icmpCode >= 0 && icmpCode <= 16)) {
|
|
s_logger.warn("Icmp code should be within 0-16 range");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static boolean isValidIp6(final String ip) {
|
|
if (ip == null)
|
|
return false;
|
|
|
|
final InetAddressValidator validator = InetAddressValidator.getInstance();
|
|
return validator.isValidInet6Address(ip);
|
|
}
|
|
|
|
public static boolean isValidIp6Cidr(final String ip6Cidr) {
|
|
try {
|
|
IPv6Network.fromString(ip6Cidr);
|
|
} catch (final IllegalArgumentException ex) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static int getIp6CidrSize(final String ip6Cidr) {
|
|
IPv6Network network = null;
|
|
try {
|
|
network = IPv6Network.fromString(ip6Cidr);
|
|
} catch (final IllegalArgumentException ex) {
|
|
return 0;
|
|
}
|
|
return network.getNetmask().asPrefixLength();
|
|
}
|
|
|
|
// Can cover 127 bits
|
|
public static String getIp6FromRange(final String ip6Range) {
|
|
final String[] ips = ip6Range.split("-");
|
|
final String startIp = ips[0];
|
|
final IPv6Address start = IPv6Address.fromString(startIp);
|
|
final BigInteger gap = countIp6InRange(ip6Range);
|
|
BigInteger next = new BigInteger(gap.bitLength(), s_rand);
|
|
while (next.compareTo(gap) >= 0) {
|
|
next = new BigInteger(gap.bitLength(), s_rand);
|
|
}
|
|
InetAddress resultAddr = null;
|
|
final BigInteger startInt = convertIPv6AddressToBigInteger(start);
|
|
if (startInt != null) {
|
|
final BigInteger resultInt = startInt.add(next);
|
|
try {
|
|
resultAddr = InetAddress.getByAddress(resultInt.toByteArray());
|
|
} catch (final UnknownHostException e) {
|
|
return null;
|
|
}
|
|
}
|
|
if( resultAddr != null) {
|
|
final IPv6Address ip = IPv6Address.fromInetAddress(resultAddr);
|
|
return ip.toString();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
//RFC3315, section 9.4
|
|
public static String getDuidLL(final String macAddress) {
|
|
final String duid = "00:03:00:01:" + macAddress;
|
|
return duid;
|
|
}
|
|
|
|
private static BigInteger convertIPv6AddressToBigInteger(final IPv6Address addr) {
|
|
InetAddress inetAddr;
|
|
try {
|
|
inetAddr = addr.toInetAddress();
|
|
} catch (final UnknownHostException e) {
|
|
return null;
|
|
}
|
|
return new BigInteger(inetAddr.getAddress());
|
|
}
|
|
|
|
// Can cover 127 bits
|
|
public static BigInteger countIp6InRange(final String ip6Range) {
|
|
if (ip6Range == null) {
|
|
return null;
|
|
}
|
|
final String[] ips = ip6Range.split("-");
|
|
final String startIp = ips[0];
|
|
String endIp = ips[0];
|
|
if (ips.length > 1) {
|
|
endIp = ips[1];
|
|
}
|
|
try {
|
|
final BigInteger startInt = convertIPv6AddressToBigInteger(IPv6Address.fromString(startIp));
|
|
final BigInteger endInt = convertIPv6AddressToBigInteger(IPv6Address.fromString(endIp));
|
|
if (endInt != null && startInt != null && startInt.compareTo(endInt) <= 0) {
|
|
return endInt.subtract(startInt).add(BigInteger.ONE);
|
|
}
|
|
} catch (final IllegalArgumentException ex) {
|
|
s_logger.error("Failed to convert a string to an IPv6 address", ex);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static boolean isIp6InRange(final String ip6, final String ip6Range) {
|
|
if (ip6Range == null) {
|
|
return false;
|
|
}
|
|
final String[] ips = ip6Range.split("-");
|
|
final String startIp = ips[0];
|
|
String endIp = null;
|
|
if (ips.length > 1) {
|
|
endIp = ips[1];
|
|
}
|
|
final IPv6Address start = IPv6Address.fromString(startIp);
|
|
final IPv6Address end = IPv6Address.fromString(endIp);
|
|
final IPv6Address ip = IPv6Address.fromString(ip6);
|
|
if (start.compareTo(ip) <= 0 && end.compareTo(ip) >= 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static boolean isIp6InNetwork(final IPv6Address ip, final IPv6Network network) {
|
|
return network.contains(ip);
|
|
}
|
|
|
|
public static boolean isIp6InNetwork(final String ip6, final String ip6Cidr) {
|
|
try {
|
|
return isIp6InNetwork(IPv6Address.fromString(ip6), IPv6Network.fromString(ip6Cidr));
|
|
} catch (final IllegalArgumentException ex) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static boolean isIp6RangeOverlap(final String ipRange1, final String ipRange2) {
|
|
String[] ips = ipRange1.split("-");
|
|
final String startIp1 = ips[0];
|
|
String endIp1 = null;
|
|
if (ips.length > 1) {
|
|
endIp1 = ips[1];
|
|
}
|
|
final IPv6Address start1 = IPv6Address.fromString(startIp1);
|
|
final IPv6Address end1 = IPv6Address.fromString(endIp1);
|
|
final IPv6AddressRange range1 = IPv6AddressRange.fromFirstAndLast(start1, end1);
|
|
ips = ipRange2.split("-");
|
|
final String startIp2 = ips[0];
|
|
String endIp2 = null;
|
|
if (ips.length > 1) {
|
|
endIp2 = ips[1];
|
|
}
|
|
final IPv6Address start2 = IPv6Address.fromString(startIp2);
|
|
final IPv6Address end2 = IPv6Address.fromString(endIp2);
|
|
final IPv6AddressRange range2 = IPv6AddressRange.fromFirstAndLast(start2, end2);
|
|
return range1.overlaps(range2);
|
|
}
|
|
|
|
public static String getNextIp6InRange(final String currentIp, final String ipRange) {
|
|
final String[] ips = ipRange.split("-");
|
|
final String startIp = ips[0];
|
|
String endIp = null;
|
|
if (ips.length > 1) {
|
|
endIp = ips[1];
|
|
}
|
|
final IPv6Address start = IPv6Address.fromString(startIp);
|
|
final IPv6Address end = IPv6Address.fromString(endIp);
|
|
final IPv6Address current = IPv6Address.fromString(currentIp);
|
|
IPv6Address result = null;
|
|
if (current.equals(end)) {
|
|
result = start;
|
|
} else {
|
|
result = current.add(1);
|
|
}
|
|
String resultIp = null;
|
|
if (result != null) {
|
|
resultIp = result.toString();
|
|
}
|
|
return resultIp;
|
|
}
|
|
|
|
public static String standardizeIp6Address(final String ip6Addr) {
|
|
try {
|
|
return IPv6Address.fromString(ip6Addr).toString();
|
|
} catch (final IllegalArgumentException ex) {
|
|
throw new IllegalArgumentException("Invalid IPv6 address: " + ex.getMessage());
|
|
}
|
|
}
|
|
|
|
public static String standardizeMacAddress(final String macAddr) {
|
|
if (!isValidMac(macAddr)) {
|
|
return null;
|
|
}
|
|
String norm = macAddr.replace('.', ':');
|
|
norm = norm.replace('-', ':');
|
|
return long2Mac(mac2Long(norm));
|
|
}
|
|
|
|
public static String standardizeIp6Cidr(final String ip6Cidr){
|
|
try {
|
|
return IPv6Network.fromString(ip6Cidr).toString();
|
|
} catch (final IllegalArgumentException ex) {
|
|
throw new IllegalArgumentException("Invalid IPv6 CIDR: " + ex.getMessage());
|
|
}
|
|
}
|
|
|
|
static final String VLAN_PREFIX = "vlan://";
|
|
static final int VLAN_PREFIX_LENGTH = VLAN_PREFIX.length();
|
|
|
|
public static boolean isValidVlan(String vlan) {
|
|
if (null == vlan || "".equals(vlan)) {
|
|
return false;
|
|
}
|
|
if (vlan.startsWith(VLAN_PREFIX)) {
|
|
vlan = vlan.substring(VLAN_PREFIX_LENGTH);
|
|
}
|
|
try {
|
|
final int vnet = Integer.parseInt(vlan);
|
|
if (vnet <= 0 || vnet >= 4095) { // the valid range is 1- 4094
|
|
return false;
|
|
}
|
|
return true;
|
|
} catch (final NumberFormatException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static final String VLAN_UNTAGGED = "untagged";
|
|
|
|
public static boolean isSameIsolationId(String one, String other) {
|
|
// check nulls
|
|
// check empty strings
|
|
if ((one == null || one.isEmpty()) && (other == null || other.isEmpty())) {
|
|
return true;
|
|
}
|
|
if (one == null || other == null) {
|
|
return false;
|
|
}
|
|
// check 'untagged'
|
|
if (one.contains(VLAN_UNTAGGED) && other.contains(VLAN_UNTAGGED)) {
|
|
return true;
|
|
}
|
|
// if one is a number check the other as number and as 'vlan://' + number
|
|
if (one.startsWith(VLAN_PREFIX)) {
|
|
one = one.substring(VLAN_PREFIX_LENGTH);
|
|
}
|
|
if (other.startsWith(VLAN_PREFIX)) {
|
|
other = other.substring(VLAN_PREFIX_LENGTH);
|
|
}
|
|
// check valid uris or numbers
|
|
if (one.equalsIgnoreCase(other)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Attention maintainers: these pvlan functions should take into account code
|
|
// in Networks.BroadcastDomainType, where URI construction is done for other
|
|
// types of BroadcastDomainTypes
|
|
public static URI generateUriForPvlan(final String primaryVlan, final String isolatedPvlan) {
|
|
return URI.create("pvlan://" + primaryVlan + "-i" + isolatedPvlan);
|
|
}
|
|
|
|
public static URI generateUriForPvlan(final String primaryVlan, final String isolatedPvlan, final String isolatedPvlanType) {
|
|
// Defaulting to isolated for backward compatibility
|
|
if (isolatedPvlan.length() < 1) {
|
|
return generateUriForPvlan(primaryVlan, isolatedPvlan);
|
|
}
|
|
char type = isolatedPvlanType.charAt(0);
|
|
switch(type) {
|
|
case 'c':
|
|
case 'C':
|
|
return URI.create("pvlan://" + primaryVlan + "-c" + isolatedPvlan);
|
|
case 'p':
|
|
case 'P':
|
|
return URI.create("pvlan://" + primaryVlan + "-p" + primaryVlan);
|
|
default :
|
|
return generateUriForPvlan(primaryVlan, isolatedPvlan);
|
|
}
|
|
}
|
|
|
|
public static String getPrimaryPvlanFromUri(final URI uri) {
|
|
final String[] vlans = uri.getHost().split("-");
|
|
if (vlans.length < 1) {
|
|
return null;
|
|
}
|
|
return vlans[0];
|
|
}
|
|
|
|
public static String getIsolatedPvlanFromUri(final URI uri) {
|
|
final String[] vlans = uri.getHost().split("-");
|
|
if (vlans.length < 2) {
|
|
return null;
|
|
}
|
|
for (final String vlan : vlans) {
|
|
if (vlan.startsWith("i")) {
|
|
return vlan.replace("i", " ").trim();
|
|
}
|
|
if (vlan.startsWith("p")) {
|
|
return vlan.replace("p", " ").trim();
|
|
}
|
|
if (vlan.startsWith("c")) {
|
|
return vlan.replace("c", " ").trim();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static String getPvlanTypeFromUri(final URI uri) {
|
|
final String[] vlans = uri.getHost().split("-");
|
|
if (vlans.length < 2) {
|
|
return null;
|
|
}
|
|
for (final String vlan : vlans) {
|
|
if (vlan.startsWith("i")) {
|
|
return "I";
|
|
}
|
|
if (vlan.startsWith("p")) {
|
|
return "P";
|
|
}
|
|
if (vlan.startsWith("c")) {
|
|
return "C";
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static String generateMacOnIncrease(final String baseMac, final long l) {
|
|
long mac = mac2Long(baseMac);
|
|
if (l > 0xFFFFl) {
|
|
return null;
|
|
}
|
|
mac = mac + (l << 24);
|
|
mac = mac & 0x06FFFFFFFFFFl;
|
|
return long2Mac(mac);
|
|
}
|
|
|
|
public static boolean isIpWithInCidrRange(final String ipAddress, final String cidr) {
|
|
if (!isValidIp4(ipAddress)) {
|
|
return false;
|
|
}
|
|
if (!isValidIp4Cidr(cidr)) {
|
|
return false;
|
|
}
|
|
|
|
// check if the gatewayip is the part of the ip range being added.
|
|
// RFC 3021 - 31-Bit Prefixes on IPv4 Point-to-Point Links
|
|
// GW Netmask Stat IP End IP
|
|
// 192.168.24.0 - 255.255.255.254 - 192.168.24.0 - 192.168.24.1
|
|
// https://tools.ietf.org/html/rfc3021
|
|
// Added by Wilder Rodrigues
|
|
final SubnetUtils subnetUtils = new SubnetUtils(cidr);
|
|
subnetUtils.setInclusiveHostCount(true);
|
|
|
|
final boolean isInRange = subnetUtils.getInfo().isInRange(ipAddress);
|
|
|
|
return isInRange;
|
|
}
|
|
|
|
public static boolean isIpInCidrList(final InetAddress address, final String[] cidrlist) {
|
|
boolean match = false;
|
|
|
|
for (String cidr: cidrlist) {
|
|
try {
|
|
if (address instanceof Inet6Address && isValidIp6Cidr(cidr)) {
|
|
if (isIp6InNetwork(IPv6Address.fromInetAddress(address), IPv6Network.fromString(cidr))) {
|
|
match = true;
|
|
break;
|
|
}
|
|
} else if (address instanceof Inet4Address && isValidIp4Cidr(cidr)) {
|
|
if (NetUtils.isIpWithInCidrRange(address.getHostAddress(), cidr)) {
|
|
match = true;
|
|
break;
|
|
}
|
|
}
|
|
} catch (IllegalArgumentException e) {
|
|
continue;
|
|
}
|
|
}
|
|
return match;
|
|
}
|
|
|
|
public static Boolean IsIpEqualToNetworkOrBroadCastIp(final String requestedIp, final String cidr, final long size) {
|
|
assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
|
|
|
|
final long ip = ip2Long(cidr);
|
|
final long startNetMask = ip2Long(getCidrNetmask(size));
|
|
|
|
final long start = ip & startNetMask;
|
|
long end = start;
|
|
|
|
end = end >> MAX_CIDR - size;
|
|
|
|
end++;
|
|
end = (end << MAX_CIDR - size) - 1;
|
|
|
|
final long reqIp = ip2Long(requestedIp);
|
|
if (reqIp == start || reqIp == end) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
public static boolean isNetworkorBroadcastIP(String ip, String netmask){
|
|
String cidr = getCidrFromGatewayAndNetmask(ip,netmask);
|
|
final SubnetUtils subnetUtils = new SubnetUtils(cidr);
|
|
subnetUtils.setInclusiveHostCount(false);
|
|
final boolean isInRange = subnetUtils.getInfo().isInRange(ip);
|
|
return !isInRange;
|
|
}
|
|
|
|
public static IPv6Address EUI64Address(final IPv6Network cidr, final String macAddress) {
|
|
if (cidr.getNetmask().asPrefixLength() > 64) {
|
|
throw new IllegalArgumentException("IPv6 subnet " + cidr.toString() + " is not 64 bits or larger in size");
|
|
}
|
|
|
|
String mac[] = macAddress.toLowerCase().split(":");
|
|
|
|
return IPv6Address.fromString(cidr.getFirst().toString() +
|
|
Integer.toHexString(Integer.parseInt(mac[0], 16) ^ 2) +
|
|
mac[1] + ":" + mac[2] + "ff:fe" + mac[3] +":" + mac[4] + mac[5]);
|
|
}
|
|
|
|
public static IPv6Address EUI64Address(final String cidr, final String macAddress) {
|
|
return EUI64Address(IPv6Network.fromString(cidr), macAddress);
|
|
}
|
|
|
|
public static IPv6Address ipv6LinkLocal(final String macAddress) {
|
|
return EUI64Address(IPv6Network.LINK_LOCAL_NETWORK, macAddress);
|
|
}
|
|
|
|
/**
|
|
* When using StateLess Address AutoConfiguration (SLAAC) for IPv6 the addresses
|
|
* choosen by hosts in a network are based on the 48-bit MAC address and this is expanded to 64-bits
|
|
* with EUI-64
|
|
* FFFE is inserted into the address and these can be identified
|
|
*
|
|
* By converting the IPv6 Address to a byte array we can check the 11th and 12th byte to see if the
|
|
* address is EUI064.
|
|
*
|
|
* See RFC4291 for more information
|
|
*
|
|
* @param address IPv6Address to be checked
|
|
* @return True if Address is EUI-64 IPv6
|
|
*/
|
|
public static boolean isIPv6EUI64(final IPv6Address address) {
|
|
byte[] bytes = address.toByteArray();
|
|
return (bytes[11] == IPV6_EUI64_11TH_BYTE && bytes[12] == IPV6_EUI64_12TH_BYTE);
|
|
}
|
|
|
|
public static boolean isIPv6EUI64(final String address) {
|
|
return NetUtils.isIPv6EUI64(IPv6Address.fromString(address));
|
|
}
|
|
|
|
/**
|
|
* Returns true if the given IP address is IPv4 or false if it is an IPv6. If it is an invalid IP address it throws an exception.
|
|
*/
|
|
public static boolean isIpv4(String ipAddr) {
|
|
boolean isIpv4 = true;
|
|
if (ipAddr != null) {
|
|
if (!NetUtils.isValidIp4(ipAddr)) {
|
|
isIpv4 = false;
|
|
}
|
|
if (!NetUtils.isValidIp6(ipAddr) && !isIpv4) {
|
|
throw new IllegalArgumentException("Invalid ip address " + ipAddr);
|
|
}
|
|
}
|
|
return isIpv4;
|
|
}
|
|
|
|
public static String getIpv6RangeFromCidr(String ipv6Cidr) {
|
|
if (StringUtils.isEmpty(ipv6Cidr)) {
|
|
return null;
|
|
}
|
|
IPv6Network network = IPv6Network.fromString(ipv6Cidr);
|
|
return String.format("%s-%s", network.getFirst().toString(), network.getLast().toString());
|
|
}
|
|
|
|
public static boolean ipv6NetworksOverlap(IPv6Network n1, IPv6Network n2) {
|
|
IPv6Network higher = n1;
|
|
IPv6Network lower = n2;
|
|
if (lower.getNetmask().asPrefixLength() < higher.getNetmask().asPrefixLength()) {
|
|
lower = n1;
|
|
higher = n2;
|
|
}
|
|
Iterator<IPv6Network> splits = higher.split(lower.getNetmask());
|
|
while (splits.hasNext()) {
|
|
IPv6Network i = splits.next();
|
|
if (i.equals(lower)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static NetworkInterface getNetworkInterface(String nicName) {
|
|
s_logger.debug(String.format("Retrieving network interface [%s].", nicName));
|
|
nicName = StringUtils.trimToNull(nicName);
|
|
|
|
if (nicName == null) {
|
|
return null;
|
|
}
|
|
|
|
NetworkInterface nic;
|
|
try {
|
|
nic = NetworkInterface.getByName(nicName);
|
|
if (nic == null) {
|
|
s_logger.debug(String.format("Unable to get network interface for NIC [%s].", nicName));
|
|
return null;
|
|
}
|
|
|
|
return nic;
|
|
} catch (final SocketException e) {
|
|
s_logger.warn(String.format("Unable to get network interface for NIC [%s] due to [%s].", nicName, e.getMessage()), e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
}
|