package org.openstack.atlas.lb.helpers.ipstring;
import org.openstack.atlas.lb.helpers.ipstring.exceptions.IPStringConversionException;
import org.openstack.atlas.lb.helpers.ipstring.exceptions.IPCidrBlockOutOfRangeException;
import org.openstack.atlas.lb.helpers.ipstring.exceptions.IPStringException;
import org.openstack.atlas.lb.helpers.ipstring.exceptions.IPBlocksOverLapException;
import org.openstack.atlas.lb.helpers.ipstring.exceptions.IPOctetOutOfRangeException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.List;
import java.util.ArrayList;
/* Just testing */
public class IPv4ToolSet {
public static String long2ip(long ipLong) {
long o4 = (ipLong >> 24) & 0xFF;
long o3 = (ipLong >> 16) & 0xFF;
long o2 = (ipLong >> 8) & 0xFF;
long o1 = (ipLong >> 0) & 0xFF;
return String.format("%d.%d.%d.%d", o4, o3, o2, o1);
}
public static long mask_bits(int bits) throws IPStringConversionException {
long mask = 0;
long rolling_bit = 1L << 32;
int i;
String parseError = "Error parsing integer";
if (bits < 0 || bits > 32) {
throw new IPStringConversionException(parseError);
}
for (i = 1; i <= bits; i++) {
rolling_bit >>= 1;
mask |= rolling_bit;
//System.out.printf("rolling bit = %d mask = %s\n",rolling_bit,mask);
}
return mask;
}
public static List<String> ipv4BlockToIpStrings(String blockString) throws IPStringConversionException, IPOctetOutOfRangeException, IPCidrBlockOutOfRangeException {
long ip;
long lo;
long hi;
List<String> ips = new ArrayList<String>();
IPv4Range ipRange = ipv4BlockToRange(blockString);
lo = ipRange.getLo();
hi = ipRange.getHi();
for (ip = lo; ip <= hi; ip++) {
ips.add(long2ip(ip));
}
return ips;
}
public static List<String> ipv4BlocksToIpStrings(List<String> ipBlocks) throws IPBlocksOverLapException, IPStringConversionException, IPOctetOutOfRangeException, IPCidrBlockOutOfRangeException {
List<String> ipStrings = new ArrayList();
IPv4Ranges ranges = new IPv4Ranges();
for (String ipBlock : ipBlocks) {
ranges.add(ipBlock); // Will throw an overlap exception if an overlap occurs
ipStrings.addAll(ipv4BlockToIpStrings(ipBlock));
}
return ipStrings;
}
public static IPv4Range ipv4BlockToRange(String blockString) throws IPStringConversionException, IPOctetOutOfRangeException, IPCidrBlockOutOfRangeException {
long hi;
long lo;
long ipLong;
long mask;
long i;
int mask_bits = 0;
final int loMaskLimit = 0;
final int hiMaskLimit = 32;
List<String> ips = new ArrayList<String>();
Pattern blockPattern = Pattern.compile("^(.*)/(.*)$");
Matcher blockMatch = blockPattern.matcher(blockString);
String parseError = String.format("Could not parse IP block \"%s\"", blockString);
if (!blockMatch.find()) {
throw new IPStringConversionException(parseError);
}
String ipString = blockMatch.group(1);
try {
mask_bits = Integer.parseInt(blockMatch.group(2));
if (mask_bits < loMaskLimit || mask_bits > hiMaskLimit) {
String format = "/%d must be in range of %d and %d";
throw new IPCidrBlockOutOfRangeException(String.format(format, mask_bits, loMaskLimit, hiMaskLimit));
}
mask = mask_bits(mask_bits);
ipLong = ip2long(ipString);
} catch (IllegalArgumentException e) {
String errorMsg = String.format("could not convert \"%s\" to an integer in block \"%s\"",
blockMatch.group(2), blockString);
throw new IPStringConversionException(errorMsg);
}
lo = ipLong & mask;
hi = (ipLong | ~mask) & 0xFFFFFFFFL;
return new IPv4Range(lo, hi, blockString);
}
public static boolean isValid(String ip) {
long ipLong;
if(ip==null) {
return false;
}
try {
ipLong = ip2long(ip);
} catch (IPStringException ex) {
return false;
}
return true;
}
public static long ip2long(String ip) throws IPStringConversionException, IPOctetOutOfRangeException {
long out = 0;
String ippatternstr = "^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$";
Pattern ipPattern = Pattern.compile(ippatternstr);
Matcher ipMatch = ipPattern.matcher(ip);
String parseError = String.format("Could not parse IP string \"%s\"", ip);
int i = 1;
if (ipMatch.find()) {
try {
for (i = 1; i <= 4; i++) {
long octet = Long.parseLong(ipMatch.group(i));
if (octet < 0 || octet > 255) {
String errMsg = String.format("Octet %s out of range 0-255 in ip %s",
ipMatch.group(i), ip);
throw new IPOctetOutOfRangeException(errMsg);
}
out += octet << (8 * -i + 32);
}
} catch (NumberFormatException e) {
String errMsg = String.format("Could not convert %s to integer in ip \"%s\"", ipMatch.group(i), ip);
throw new IPStringConversionException(errMsg);
}
} else {
throw new IPStringConversionException(parseError);
}
return out;
}
//TODO: refactor this, temp hack to make zeus happy...
public static boolean rejectUnwantedIps(String ip) {
List<String> badIps = new ArrayList<String>();
badIps.add("0.0.0.0");
for (String ipString : badIps) {
if (ipString.equals(ip)) {
return true;
}
}
return false;
}
}