package org.openstack.atlas.util.ip;
import org.openstack.atlas.util.ip.exception.IPStringConversionException;
import org.openstack.atlas.util.ip.exception.IpTypeMissMatchException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IPv6Cidr {
private static final Pattern subnetPattern = Pattern.compile("^(.*)/(.*)$");
private String cidr;
private String ip;
private int subnet;
private byte[] ipBytes;
private byte[] maskBytes;
public IPv6Cidr() {
}
public IPv6Cidr(String cidr) throws IPStringConversionException {
this.setCidr(cidr);
}
public void setCidr(String in) throws IPStringConversionException {
String msg;
String ipStr;
String subnetStr;
Matcher ipMatcher;
if (in == null) {
throw new IPStringConversionException("INVALID SUBNET, CIDR was NULL");
}
ipMatcher = subnetPattern.matcher(in);
int subnetint;
if (ipMatcher.find()) {
ipStr = ipMatcher.group(1);
subnetStr = ipMatcher.group(2);
try {
subnetint = Integer.parseInt(subnetStr);
if (subnetint < 0 || subnetint > 128 || !IPUtils.isValidIpv6String(ipStr)) {
msg = String.format("Subnet %d not in [0,128]", subnetint);
throw new IPStringConversionException(msg);
}
this.subnet = subnetint;
} catch (NumberFormatException e) {
msg = String.format("Error converting %s to integer", subnetStr);
throw new IPStringConversionException(msg);
}
this.cidr = in;
ipBytes = new IPv6(ipStr).getBytes();
maskBytes = IPUtils.rollMask(subnetint, 16);
} else {
msg = String.format("INVALID SUBNET: %s", in);
throw new IPStringConversionException(msg);
}
}
public boolean contains(String ip) throws IPStringConversionException, IpTypeMissMatchException {
boolean out;
if(!IPUtils.isValidIpv6String(ip)) {
return false;
}
byte[] theirBytes = new IPv6(ip).getBytes();
byte[] mySubnet = IPUtils.opBytes(ipBytes, maskBytes, ByteStreamOperation.AND);
byte[] theirSubnet = IPUtils.opBytes(theirBytes, maskBytes, ByteStreamOperation.AND);
out = IPUtils.bytesEqual(theirSubnet, mySubnet);
return out;
}
public boolean matches(IPv6Cidr oCidr) throws IpTypeMissMatchException, IPStringConversionException {
if (oCidr == null) {
return false;
}
if (oCidr.getSubnet() != this.subnet) {
return false;
}
byte[] mySubnet = IPUtils.opBytes(ipBytes, maskBytes, ByteStreamOperation.AND);
byte[] theirSubnet = IPUtils.opBytes(oCidr.getIpBytes(), maskBytes, ByteStreamOperation.AND);
for (int i = 0; i < mySubnet.length; i++) {
if (mySubnet[i] != theirSubnet[i]) {
return false;
}
}
return true;
}
public String getExpandedIPv6Cidr(String cidr) throws IPStringConversionException {
String block = cidr.substring(cidr.indexOf("/"));
return new IPv6(cidr.substring(0, cidr.indexOf("/"))).expand() + block;
}
public String getCidr() {
return cidr;
}
public String getIp() {
return ip;
}
public int getSubnet() {
return subnet;
}
public byte[] getIpBytes() {
return ipBytes;
}
public byte[] getMaskBytes() {
return maskBytes;
}
}