Changes to Prefix to support new PATRICIA Trie
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
index 54775df..c40214b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
@@ -2,30 +2,89 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.Arrays;
public class Prefix {
- private int prefixLength;
- private InetAddress address;
+ private final int MAX_BYTES = 4;
+
+ private final int prefixLength;
+ private final byte[] address;
+
+ //For verifying the arguments and pretty printing
+ private final InetAddress inetAddress;
+
+ public Prefix(byte[] addr, int prefixLength) {
+ if (addr == null || addr.length != MAX_BYTES ||
+ prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+ throw new IllegalArgumentException();
+ }
- public Prefix(byte[] addr, int prefixLength) throws UnknownHostException {
- //try {
- address = InetAddress.getByAddress(addr);
- //} catch (UnknownHostException e) {
- // System.out.println("InetAddress exception");
- // return;
- //}
+ address = canonicalizeAddress(addr, prefixLength);
this.prefixLength = prefixLength;
- //System.out.println(address.toString() + "/" + prefixLength);
+
+ try {
+ inetAddress = InetAddress.getByAddress(address);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException();
+ }
}
- public Prefix(String str, int prefixLength) throws UnknownHostException {
- //try {
- address = InetAddress.getByName(str);
- //} catch (UnknownHostException e) {
- // System.out.println("InetAddress exception");
- // return;
- //}
+ public Prefix(String strAddress, int prefixLength) {
+ byte[] addr = null;
+ try {
+ addr = InetAddress.getByName(strAddress).getAddress();
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Invalid IP inetAddress argument");
+ }
+
+ if (addr == null || addr.length != MAX_BYTES ||
+ prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+ throw new IllegalArgumentException();
+ }
+
+ address = canonicalizeAddress(addr, prefixLength);
this.prefixLength = prefixLength;
+
+ try {
+ inetAddress = InetAddress.getByAddress(address);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
+ byte[] result = new byte[address.length];
+
+ if (prefixLength == 0) {
+ for (int i = 0; i < MAX_BYTES; i++) {
+ result[i] = 0;
+ }
+
+ return result;
+ }
+
+ result = Arrays.copyOf(address, address.length);
+
+ //Set all bytes after the end of the prefix to 0
+ int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
+ for (int i = lastByteIndex; i < MAX_BYTES; i++) {
+ result[i] = 0;
+ }
+
+ byte lastByte = address[lastByteIndex];
+ byte mask = 0;
+ byte lsb = 1;
+ int lastBit = (prefixLength - 1) % Byte.SIZE;
+ for (int i = 0; i < Byte.SIZE; i++) {
+ if (i <= lastBit + 1) {
+ mask |= lsb;
+ }
+ mask <<= 1;
+ }
+
+ result[lastByteIndex] = (byte) (lastByte & mask);
+
+ return result;
}
public int getPrefixLength() {
@@ -33,7 +92,7 @@
}
public byte[] getAddress() {
- return address.getAddress();
+ return address;
}
@Override
@@ -44,7 +103,7 @@
Prefix otherPrefix = (Prefix) other;
- return (address.equals(otherPrefix.address)) &&
+ return (Arrays.equals(address, otherPrefix.address)) &&
(prefixLength == otherPrefix.prefixLength);
}
@@ -52,12 +111,28 @@
public int hashCode() {
int hash = 17;
hash = 31 * hash + prefixLength;
- hash = 31 * hash + (address == null ? 0 : address.hashCode());
+ hash = 31 * hash + Arrays.hashCode(address);
return hash;
}
@Override
public String toString() {
- return address.getHostAddress() + "/" + prefixLength;
+ return inetAddress.getHostAddress() + "/" + prefixLength;
+ }
+
+ public String printAsBits() {
+ String result = "";
+ for (int i = 0; i < address.length; i++) {
+ byte b = address[i];
+ for (int j = 0; j < Byte.SIZE; j++) {
+ byte mask = (byte) (0x80 >>> j);
+ result += ((b & mask) == 0)? "0" : "1";
+ if (i*Byte.SIZE+j == prefixLength-1) {
+ return result;
+ }
+ }
+ result += " ";
+ }
+ return result.substring(0, result.length() - 1);
}
}