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);
- }
}