2016-03-29 11:28:55 +00:00
|
|
|
package eu.faircode.netguard;
|
|
|
|
|
|
|
|
/*
|
|
|
|
This file is part of NetGuard.
|
|
|
|
|
|
|
|
NetGuard is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
NetGuard is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with NetGuard. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2016-12-29 08:27:58 +00:00
|
|
|
Copyright 2015-2017 by Marcel Bokhorst (M66B)
|
2016-03-29 11:28:55 +00:00
|
|
|
*/
|
|
|
|
|
2017-08-05 08:27:27 +00:00
|
|
|
import android.support.annotation.NonNull;
|
2016-03-29 11:28:55 +00:00
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.net.UnknownHostException;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
public class IPUtil {
|
|
|
|
private static final String TAG = "NetGuard.IPUtil";
|
|
|
|
|
|
|
|
public static List<CIDR> toCIDR(String start, String end) throws UnknownHostException {
|
|
|
|
return toCIDR(InetAddress.getByName(start), InetAddress.getByName(end));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static List<CIDR> toCIDR(InetAddress start, InetAddress end) throws UnknownHostException {
|
|
|
|
List<CIDR> listResult = new ArrayList<>();
|
|
|
|
|
|
|
|
Log.i(TAG, "toCIDR(" + start.getHostAddress() + "," + end.getHostAddress() + ")");
|
|
|
|
|
|
|
|
long from = inet2long(start);
|
|
|
|
long to = inet2long(end);
|
|
|
|
while (to >= from) {
|
|
|
|
byte prefix = 32;
|
|
|
|
while (prefix > 0) {
|
2016-03-29 16:30:04 +00:00
|
|
|
long mask = prefix2mask(prefix - 1);
|
2016-03-29 11:28:55 +00:00
|
|
|
if ((from & mask) != from)
|
|
|
|
break;
|
|
|
|
prefix--;
|
|
|
|
}
|
|
|
|
|
|
|
|
byte max = (byte) (32 - Math.floor(Math.log(to - from + 1) / Math.log(2)));
|
|
|
|
if (prefix < max)
|
|
|
|
prefix = max;
|
|
|
|
|
|
|
|
listResult.add(new CIDR(long2inet(from), prefix));
|
|
|
|
|
|
|
|
from += Math.pow(2, (32 - prefix));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (CIDR cidr : listResult)
|
|
|
|
Log.i(TAG, cidr.toString());
|
|
|
|
|
|
|
|
return listResult;
|
|
|
|
}
|
|
|
|
|
2016-03-29 16:30:04 +00:00
|
|
|
private static long prefix2mask(int bits) {
|
|
|
|
return (0xFFFFFFFF00000000L >> bits) & 0xFFFFFFFFL;
|
|
|
|
}
|
|
|
|
|
2016-03-29 11:28:55 +00:00
|
|
|
private static long inet2long(InetAddress addr) {
|
|
|
|
long result = 0;
|
2016-05-14 15:48:59 +00:00
|
|
|
if (addr != null)
|
|
|
|
for (byte b : addr.getAddress())
|
|
|
|
result = result << 8 | (b & 0xFF);
|
2016-03-29 11:28:55 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-03-29 16:30:04 +00:00
|
|
|
private static InetAddress long2inet(long addr) {
|
|
|
|
try {
|
|
|
|
byte[] b = new byte[4];
|
|
|
|
for (int i = b.length - 1; i >= 0; i--) {
|
|
|
|
b[i] = (byte) (addr & 0xFF);
|
|
|
|
addr = addr >> 8;
|
|
|
|
}
|
|
|
|
return InetAddress.getByAddress(b);
|
|
|
|
} catch (UnknownHostException ignore) {
|
|
|
|
return null;
|
2016-03-29 11:28:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-29 16:30:04 +00:00
|
|
|
public static InetAddress minus1(InetAddress addr) {
|
|
|
|
return long2inet(inet2long(addr) - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static InetAddress plus1(InetAddress addr) {
|
|
|
|
return long2inet(inet2long(addr) + 1);
|
2016-03-29 11:28:55 +00:00
|
|
|
}
|
|
|
|
|
2016-03-29 16:30:04 +00:00
|
|
|
public static class CIDR implements Comparable<CIDR> {
|
2016-03-29 11:28:55 +00:00
|
|
|
public InetAddress address;
|
|
|
|
public int prefix;
|
|
|
|
|
|
|
|
public CIDR(InetAddress address, int prefix) {
|
|
|
|
this.address = address;
|
|
|
|
this.prefix = prefix;
|
|
|
|
}
|
|
|
|
|
2016-03-29 16:30:04 +00:00
|
|
|
public CIDR(String ip, int prefix) {
|
|
|
|
try {
|
|
|
|
this.address = InetAddress.getByName(ip);
|
|
|
|
this.prefix = prefix;
|
|
|
|
} catch (UnknownHostException ex) {
|
|
|
|
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public InetAddress getStart() {
|
|
|
|
return long2inet(inet2long(this.address) & prefix2mask(this.prefix));
|
|
|
|
}
|
|
|
|
|
|
|
|
public InetAddress getEnd() {
|
|
|
|
return long2inet((inet2long(this.address) & prefix2mask(this.prefix)) + (1L << (32 - this.prefix)) - 1);
|
|
|
|
}
|
|
|
|
|
2016-03-29 11:28:55 +00:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
2016-03-29 16:30:04 +00:00
|
|
|
return address.getHostAddress() + "/" + prefix + "=" + getStart().getHostAddress() + "..." + getEnd().getHostAddress();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-08-05 08:27:27 +00:00
|
|
|
public int compareTo(@NonNull CIDR other) {
|
2016-03-29 16:30:04 +00:00
|
|
|
Long lcidr = IPUtil.inet2long(this.address);
|
|
|
|
Long lother = IPUtil.inet2long(other.address);
|
|
|
|
return lcidr.compareTo(lother);
|
2016-03-29 11:28:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|