Repository: cloudstack Updated Branches: refs/heads/master 0552039a8 -> 75463356f
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/75463356/utils/src/com/cloud/utils/net/NetUtils.java ---------------------------------------------------------------------- diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 19dec36..2cd4753 100644 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -54,6 +54,10 @@ 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 String HTTP_PORT = "80"; public final static String HTTPS_PORT = "443"; public final static int VPN_PORT = 500; @@ -144,7 +148,7 @@ public class NetUtils { for (final InterfaceAddress address : ifc.getInterfaceAddresses()) { final InetAddress addr = address.getAddress(); final int prefixLength = address.getNetworkPrefixLength(); - if (prefixLength < 32 && prefixLength > 0) { + if (prefixLength < MAX_CIDR && prefixLength > 0) { final String ip = ipFromInetAddress(addr); if (ip.equalsIgnoreCase(defaultHostIp)) { cidrList.add(ipAndNetMaskToCidr(ip, getCidrNetmask(prefixLength))); @@ -346,6 +350,12 @@ public class NetUtils { return macAddressAsLong; } + /** + * 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; @@ -358,17 +368,6 @@ public class NetUtils { endIp2Long = ip2Long(endIp2); } - // 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 int ip31bitPrefixOffSet = 1; - if (startIp2Long - startIp1Long == startIp2Long - (endIp1Long - ip31bitPrefixOffSet)) { - return false; - } - if (startIp1Long == startIp2Long || startIp1Long == endIp2Long || endIp1Long == startIp2Long || endIp1Long == endIp2Long) { return true; } else if (startIp1Long > startIp2Long && startIp1Long < endIp2Long) { @@ -538,6 +537,20 @@ public class NetUtils { return validator.isValidInet4Address(ip); } + public static boolean is31PrefixCidr(final String cidr) { + final boolean isValidCird = isValidCIDR(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 isValidCIDR(final String cidr) { if (cidr == null || cidr.isEmpty()) { return false; @@ -559,7 +572,7 @@ public class NetUtils { return false; } - if (cidrSizeNum < 0 || cidrSizeNum > 32) { + if (cidrSizeNum < 0 || cidrSizeNum > MAX_CIDR) { return false; } @@ -620,17 +633,17 @@ public class NetUtils { } public static String[] getIpRangeFromCidr(final String cidr, final long size) { - assert size < 32 : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + 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 >> 32 - size; + end = end >> MAX_CIDR - size; end++; - end = (end << 32 - size) - 2; + end = (end << MAX_CIDR - size) - 2; result[0] = long2Ip(start); result[1] = long2Ip(end); @@ -639,17 +652,17 @@ public class NetUtils { } public static Set<Long> getAllIpsFromCidr(final String cidr, final long size, final Set<Long> usedIps) { - assert size < 32 : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size; + 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 >> 32 - size; + end = end >> MAX_CIDR - size; end++; - end = (end << 32 - size) - 2; + end = (end << MAX_CIDR - size) - 2; int maxIps = 255; // get 255 ips as maximum while (start <= end && maxIps > 0) { if (!usedIps.contains(start)) { @@ -687,11 +700,11 @@ public class NetUtils { * @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 < 32 : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + 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 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 << 32 - size; //e.g., /24 = 2^8 = 256 + 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) { @@ -727,10 +740,10 @@ public class NetUtils { final long startNetMask = ip2Long(getCidrNetmask(size)); final long start = (ip & startNetMask) + 1; long end = start; - end = end >> 32 - size; + end = end >> MAX_CIDR - size; end++; - end = (end << 32 - size) - 2; + end = (end << MAX_CIDR - size) - 2; return long2Ip(end); } @@ -762,7 +775,7 @@ public class NetUtils { } public static String getCidrSubNet(final String ip, final long cidrSize) { - final long numericNetmask = 0xffffffff >> 32 - cidrSize << 32 - cidrSize; + final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSize << MAX_CIDR - cidrSize; final String netmask = NetUtils.long2Ip(numericNetmask); return getSubNet(ip, netmask); } @@ -797,10 +810,10 @@ public class NetUtils { while ((subnet = subnet >> 1 & subnet) != 0) { bits++; } - end = end >> 32 - bits; + end = end >> MAX_CIDR - bits; end++; - end = (end << 32 - bits) - 2; + end = (end << MAX_CIDR - bits) - 2; return new String[] {long2Ip(start), long2Ip(end)}; @@ -824,9 +837,9 @@ public class NetUtils { return SupersetOrSubset.errorInCidrFormat; } if (cidrALong[1] >= cidrBLong[1]) { - shift = 32 - cidrBLong[1]; + shift = MAX_CIDR - cidrBLong[1]; } else { - shift = 32 - cidrALong[1]; + shift = MAX_CIDR - cidrALong[1]; } final long result = (cidrALong[0] >> shift) - (cidrBLong[0] >> shift); if (result == 0) { @@ -850,7 +863,7 @@ public class NetUtils { if (cidrALong == null || cidrBLong == null) { return false; } - final long shift = 32 - cidrBLong[1]; + final long shift = MAX_CIDR - cidrBLong[1]; return cidrALong[0] >> shift == cidrBLong[0] >> shift; } @@ -874,7 +887,7 @@ public class NetUtils { } catch (final Exception e) { return null; } - final long numericNetmask = 0xffffffff >> 32 - cidrSizeNum << 32 - cidrSizeNum; + final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSizeNum << MAX_CIDR - cidrSizeNum; final long ipAddr = ip2Long(cidrAddress); final Long[] cidrlong = {ipAddr & numericNetmask, (long)cidrSizeNum}; return cidrlong; @@ -901,13 +914,13 @@ public class NetUtils { } catch (final Exception e) { return null; } - final long numericNetmask = 0xffffffff >> 32 - cidrSizeNum << 32 - cidrSizeNum; + final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSizeNum << MAX_CIDR - cidrSizeNum; final String netmask = NetUtils.long2Ip(numericNetmask); return getSubNet(cidrAddress, netmask); } public static String getCidrNetmask(final long cidrSize) { - final long numericNetmask = 0xffffffff >> 32 - cidrSize << 32 - cidrSize; + final long numericNetmask = 0xffffffff >> MAX_CIDR - cidrSize << MAX_CIDR - cidrSize; return long2Ip(numericNetmask); } @@ -925,7 +938,7 @@ public class NetUtils { public static long getCidrSize(final String netmask) { final long ip = ip2Long(netmask); int count = 0; - for (int i = 0; i < 32; i++) { + for (int i = 0; i < MAX_CIDR; i++) { if ((ip >> i & 0x1) == 0) { count++; } else { @@ -933,7 +946,7 @@ public class NetUtils { } } - return 32 - count; + return MAX_CIDR - count; } public static boolean isValidPort(final String p) { @@ -995,7 +1008,7 @@ public class NetUtils { return null; } /* reserve gateway */ - final String[] range = getIpRangeFromCidr(getLinkLocalGateway(), 32 - size); + final String[] range = getIpRangeFromCidr(getLinkLocalGateway(), MAX_CIDR - size); if (range[0].equalsIgnoreCase(getLinkLocalGateway())) { /* remove the gateway */ @@ -1010,7 +1023,7 @@ public class NetUtils { final String[] cidrPair = getLinkLocalCIDR().split("\\/"); final String cidr = cidrPair[0]; - return getIpRangeEndIpFromCidr(cidr, 32 - Long.parseLong(cidrPair[1])); + return getIpRangeEndIpFromCidr(cidr, MAX_CIDR - Long.parseLong(cidrPair[1])); } public static String portRangeToString(final int portRange[]) { @@ -1140,7 +1153,7 @@ public class NetUtils { if (cidrALong == null || cidrBLong == null) { return false; } - final long shift = 32 - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]); + final long shift = MAX_CIDR - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]); return cidrALong[0] >> shift == cidrBLong[0] >> shift; } @@ -1514,7 +1527,7 @@ public class NetUtils { } public static Boolean IsIpEqualToNetworkOrBroadCastIp(final String requestedIp, final String cidr, final long size) { - assert size < 32 : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + 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)); @@ -1522,10 +1535,10 @@ public class NetUtils { final long start = ip & startNetMask; long end = start; - end = end >> 32 - size; + end = end >> MAX_CIDR - size; end++; - end = (end << 32 - size) - 1; + end = (end << MAX_CIDR - size) - 1; final long reqIp = ip2Long(requestedIp); if (reqIp == start || reqIp == end) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/75463356/utils/test/com/cloud/utils/net/NetUtilsTest.java ---------------------------------------------------------------------- diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java index 0130b9a..1ab4459 100644 --- a/utils/test/com/cloud/utils/net/NetUtilsTest.java +++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java @@ -378,13 +378,7 @@ public class NetUtilsTest { String ip1; String ip2; - // 192.168.0.0 - 192.168.0.0 - 192.168.0.1 - // GW and IP1 overlaps, but in that case it's a 31bit IP. - // 192.168.0.0 - 192.168.0.1 - 192.168.0.2 - // GW and IP1 overlaps, but in that case it's a 31bit IP. - // and so on. - - for (int i = 0, j = 1; i <= 254; i++, j++) { + for (int i = 1, j = 2; i <= 254; i++, j++) { ip1 = "192.168.0." + i; ip2 = "192.168.0." + j; @@ -399,9 +393,6 @@ public class NetUtilsTest { String ip1; String ip2; - // 192.168.0.10 - 192.168.0.10 - 192.168.0.12 - // GW and IP1 overlaps and in that case it's not a 31bit IP. - for (int i = 10, j = 12; i <= 254; i++, j++) { gw = "192.168.0." + i; ip1 = "192.168.0." + i; @@ -411,4 +402,20 @@ public class NetUtilsTest { assertTrue("It overlaps!", doesOverlap); } } + + @Test + public void testIs31PrefixCidrFail() { + final String cidr = "10.10.0.0/32"; + final boolean is31PrefixCidr = NetUtils.is31PrefixCidr(cidr); + + assertFalse("It should fail! 32 bit prefix.", is31PrefixCidr); + } + + @Test + public void testIs31PrefixCidr() { + final String cidr = "10.10.0.0/31"; + final boolean is31PrefixCidr = NetUtils.is31PrefixCidr(cidr); + + assertTrue("It should pass! 31 bit prefix.", is31PrefixCidr); + } } \ No newline at end of file
