blob: 8539759bf50c338bbf8db15192996dae3750095b [file] [log] [blame]
package net.onrc.onos.apps.bgproute;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import com.google.common.net.InetAddresses;
public class Prefix {
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();
}
address = canonicalizeAddress(addr, prefixLength);
this.prefixLength = prefixLength;
try {
inetAddress = InetAddress.getByAddress(address);
} catch (UnknownHostException e) {
throw new IllegalArgumentException();
}
}
public Prefix(String strAddress, int prefixLength) {
byte[] addr = null;
addr = InetAddresses.forString(strAddress).getAddress();
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 msb = (byte) 0x80;
int lastBit = (prefixLength - 1) % Byte.SIZE;
for (int i = 0; i < Byte.SIZE; i++) {
if (i <= lastBit) {
mask |= (msb >> i);
}
}
result[lastByteIndex] = (byte) (lastByte & mask);
return result;
}
public int getPrefixLength() {
return prefixLength;
}
public byte[] getAddress() {
return address;
}
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof Prefix)) {
return false;
}
Prefix otherPrefix = (Prefix) other;
return (Arrays.equals(address, otherPrefix.address)) &&
(prefixLength == otherPrefix.prefixLength);
}
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + prefixLength;
hash = 31 * hash + Arrays.hashCode(address);
return hash;
}
@Override
public String toString() {
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);
}
}