You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2017/03/11 14:57:54 UTC

svn commit: r1786511 - in /commons/proper/net/trunk/src: changes/changes.xml main/java/org/apache/commons/net/util/SubnetUtils.java

Author: sebb
Date: Sat Mar 11 14:57:54 2017
New Revision: 1786511

URL: http://svn.apache.org/viewvc?rev=1786511&view=rev
Log:
NET-625 SubnetUtils - improve construction
Also make most fields final

Modified:
    commons/proper/net/trunk/src/changes/changes.xml
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java

Modified: commons/proper/net/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1786511&r1=1786510&r2=1786511&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/net/trunk/src/changes/changes.xml [utf-8] Sat Mar 11 14:57:54 2017
@@ -71,6 +71,9 @@ This is mainly a bug-fix release. See fu
  However it is not source compatible with releases before 3.4, as some methods were added to the interface NtpV3Packet in 3.4
         
 ">
+            <action issue="NET-625" type="update" dev="sebb">
+            SubnetUtils - improve construction
+            </action>
             <action issue="NET-624" type="update" dev="sebb" due-to="Makoto Sakaguchi">
             SubnetInfo#getCidrSignature - improve functions
             </action>

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java?rev=1786511&r1=1786510&r2=1786511&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java Sat Mar 11 14:57:54 2017
@@ -32,10 +32,10 @@ public class SubnetUtils {
     private static final Pattern cidrPattern = Pattern.compile(SLASH_FORMAT);
     private static final int NBITS = 32;
 
-    private int netmask = 0;
-    private int address = 0;
-    private int network = 0;
-    private int broadcast = 0;
+    private final int netmask;
+    private final int address;
+    private final int network;
+    private final int broadcast;
 
     /** Whether the broadcast/network address are included in host count */
     private boolean inclusiveHostCount = false;
@@ -48,7 +48,32 @@ public class SubnetUtils {
      * i.e. does not match n.n.n.n/m where n=1-3 decimal digits, m = 1-2 decimal digits in range 1-32
      */
     public SubnetUtils(String cidrNotation) {
-        calculate(cidrNotation);
+      Matcher matcher = cidrPattern.matcher(cidrNotation);
+
+      if (matcher.matches()) {
+          this.address = matchAddress(matcher);
+
+          /* Create a binary netmask from the number of bits specification /x */
+
+          int trailingZeroes = NBITS - rangeCheck(Integer.parseInt(matcher.group(5)), 0, NBITS);
+          /*
+           * An IPv4 netmask consists of 32 bits, a contiguous sequence 
+           * of the specified number of ones followed by all zeros.
+           * So, it can be obtained by shifting an unsigned integer (32 bits) to the left by
+           * the number of trailing zeros which is (32 - the # bits specification).
+           * Note that there is no unsigned left shift operator, so we have to use
+           * a long to ensure that the left-most bit is shifted out correctly.
+           */
+          this.netmask = (int) (0x0FFFFFFFFL << trailingZeroes );
+
+          /* Calculate base network address */
+          this.network = (address & netmask);
+
+          /* Calculate broadcast address */
+          this.broadcast = network | ~(netmask);
+      } else {
+          throw new IllegalArgumentException("Could not parse [" + cidrNotation + "]");
+      }
     }
 
     /**
@@ -59,7 +84,18 @@ public class SubnetUtils {
      * i.e. does not match n.n.n.n where n=1-3 decimal digits and the mask is not all zeros
      */
     public SubnetUtils(String address, String mask) {
-        calculate(toCidrNotation(address, mask));
+        this.address = toInteger(address);
+        this.netmask = toInteger(mask);
+
+        if ((this.netmask & -this.netmask) - 1 != ~this.netmask) {
+            throw new IllegalArgumentException("Could not parse [" + mask + "]");
+        }
+
+        /* Calculate base network address */
+        this.network = (this.address & this.netmask);
+
+        /* Calculate broadcast address */
+        this.broadcast = this.network | ~(this.netmask);
     }
 
 
@@ -244,41 +280,9 @@ public class SubnetUtils {
     public final SubnetInfo getInfo() { return new SubnetInfo(); }
 
     /*
-     * Initialize the internal fields from the supplied CIDR mask
-     */
-    private void calculate(String mask) {
-        Matcher matcher = cidrPattern.matcher(mask);
-
-        if (matcher.matches()) {
-            address = matchAddress(matcher);
-
-            /* Create a binary netmask from the number of bits specification /x */
-
-            int trailingZeroes = NBITS - rangeCheck(Integer.parseInt(matcher.group(5)), 0, NBITS);
-            /*
-             * An IPv4 netmask consists of 32 bits, a contiguous sequence 
-             * of the specified number of ones followed by all zeros.
-             * So, it can be obtained by shifting an unsigned integer (32 bits) to the left by
-             * the number of trailing zeros which is (32 - the # bits specification).
-             * Note that there is no unsigned left shift operator, so we have to use
-             * a long to ensure that the left-most bit is shifted out correctly.
-             */
-            netmask = (int) (0x0FFFFFFFFL << trailingZeroes );
-
-            /* Calculate base network address */
-            network = (address & netmask);
-
-            /* Calculate broadcast address */
-            broadcast = network | ~(netmask);
-        } else {
-            throw new IllegalArgumentException("Could not parse [" + mask + "]");
-        }
-    }
-
-    /*
      * Convert a dotted decimal format address to a packed integer format
      */
-    private int toInteger(String address) {
+    private static int toInteger(String address) {
         Matcher matcher = addressPattern.matcher(address);
         if (matcher.matches()) {
             return matchAddress(matcher);
@@ -291,7 +295,7 @@ public class SubnetUtils {
      * Convenience method to extract the components of a dotted decimal address and
      * pack into an integer using a regex match
      */
-    private int matchAddress(Matcher matcher) {
+    private static int matchAddress(Matcher matcher) {
         int addr = 0;
         for (int i = 1; i <= 4; ++i) {
             int n = (rangeCheck(Integer.parseInt(matcher.group(i)), 0, 255));
@@ -330,7 +334,7 @@ public class SubnetUtils {
      * Checks if a value x is in the range [begin,end].
      * Returns x if it is in range, throws an exception otherwise.
      */
-    private int rangeCheck(int value, int begin, int end) {
+    private static int rangeCheck(int value, int begin, int end) {
         if (value >= begin && value <= end) { // (begin,end]
             return value;
         }
@@ -351,25 +355,4 @@ public class SubnetUtils {
         return x & 0x0000003F;
     }
 
-    /*
-     * Convert two dotted decimal addresses to a single xxx.xxx.xxx.xxx/yy format
-     * by counting the 1-bit population in the mask address. (It may be better to count
-     * NBITS-#trailing zeroes for this case)
-     */
-    private String toCidrNotation(String addr, String mask) {
-        int maskInt = toInteger(mask);
-
-        /*
-         * Check the subnet mask
-         *
-         * An IPv4 subnet mask must consist of a set of contiguous 1-bits followed by a block of 0-bits.
-         * If the mask follows the format, the numbers of subtracting one from the lowest one bit of the mask,
-         * see Hacker's Delight section 2.1, equals to the bitwise complement of the mask.
-         */
-        if ((maskInt & -maskInt) - 1 != ~maskInt) {
-            throw new IllegalArgumentException("Could not parse [" + mask + "]");
-        }
-
-        return addr + "/" + pop(maskInt);
-    }
 }