package org.batfish.datamodel;
import java.io.Serializable;
import java.math.BigInteger;
import org.batfish.common.BatfishException;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
public class Prefix6 implements Comparable<Prefix6>, Serializable {
public static final int MAX_PREFIX_LENGTH = 128;
/**
*
*/
private static final long serialVersionUID = 1L;
public static final Prefix6 ZERO = new Prefix6(Ip6.ZERO, 0);
private static BigInteger getNetworkEnd(BigInteger networkStart,
int prefix_length) {
BigInteger networkEnd = networkStart;
int ones_length = MAX_PREFIX_LENGTH - prefix_length;
for (int i = 0; i < ones_length; i++) {
networkEnd = networkEnd.or(BigInteger.ONE.shiftLeft(i));
}
return networkEnd;
}
private static BigInteger numWildcardBitsToWildcardBigInteger(int numBits) {
BigInteger wildcard = BigInteger.ZERO;
for (int i = 0; i < numBits; i++) {
wildcard = wildcard.or(BigInteger.ONE.shiftLeft(i));
}
return wildcard;
}
private Ip6 _address;
private int _prefixLength;
public Prefix6(Ip6 network, int prefixLength) {
_address = network;
_prefixLength = prefixLength;
}
public Prefix6(Ip6 address, Ip6 mask) {
if (address == null) {
throw new BatfishException("Cannot create prefix6 with null network");
}
if (mask == null) {
throw new BatfishException("Cannot create prefix6 with null mask");
}
_address = address;
_prefixLength = mask.numSubnetBits();
}
@JsonCreator
public Prefix6(String text) {
String[] parts = text.split("/");
if (parts.length != 2) {
throw new BatfishException("Invalid Prefix6 string: \"" + text + "\"");
}
_address = new Ip6(parts[0]);
try {
_prefixLength = Integer.parseInt(parts[1]);
}
catch (NumberFormatException e) {
throw new BatfishException(
"Invalid Prefix6 length: \"" + parts[1] + "\"", e);
}
}
@Override
public int compareTo(Prefix6 rhs) {
int ret = _address.compareTo(rhs._address);
if (ret != 0) {
return ret;
}
return Integer.compare(_prefixLength, rhs._prefixLength);
}
public boolean contains(Ip6 Ip6) {
BigInteger start = getNetworkAddress().asBigInteger();
BigInteger end = getEndAddress().asBigInteger();
BigInteger ipAsLong = Ip6.asBigInteger();
return (start.compareTo(ipAsLong) <= 0 && ipAsLong.compareTo(end) <= 0);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
Prefix6 rhs = (Prefix6) obj;
return _address.equals(rhs._address)
&& _prefixLength == rhs._prefixLength;
}
public Ip6 getAddress() {
return _address;
}
public Ip6 getEndAddress() {
return new Ip6(getNetworkEnd(_address.asBigInteger(), _prefixLength));
}
public Ip6 getNetworkAddress() {
return _address.getNetworkAddress(_prefixLength);
}
public Prefix6 getNetworkPrefix() {
return new Prefix6(getNetworkAddress(), _prefixLength);
}
public int getPrefixLength() {
return _prefixLength;
}
public Ip6 getPrefixWildcard() {
int numWildcardBits = MAX_PREFIX_LENGTH - _prefixLength;
BigInteger wildcardBigInteger = numWildcardBitsToWildcardBigInteger(
numWildcardBits);
return new Ip6(wildcardBigInteger);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + _address.hashCode();
result = prime * result + _prefixLength;
return result;
}
@Override
@JsonValue
public String toString() {
return _address.toString() + "/" + _prefixLength;
}
}