Pavlin Radoslavov

IpAddress and IpPrefix related cleanup:

 * Removed IpAddress.MAX_INET_MASK and use IpPrefix.MAX_INET_MASK_LENGTH
   instead
 * Renamed IpAddress.INET_LEN to INET_BYTE_LENGTH
 * Added IpAddress.INET_BIT_LENGTH, INET6_BYTE_LENGTH, and INET6_BIT_LENGTH
 * Removed methods that are semantically incorrect, or are not needed/used
   - IpAddress.prefixLength()
   - IpAddress.toPrefix()
   - IpAddress.mask()
   - IpAddress.netmask()
   - IpAddress.network()
   - IpAddress.host()
   - IpAddress.isMasked()
   - IpAddress.contains()
   - IpPrefix constructor for version and bytes (but no netmask)
   - IpPrefix.valueOf(int)

 * Misc. other cleanup.
......@@ -148,9 +148,9 @@ public class PeerConnectivityManager {
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchTcpDst((short) BgpConstants.BGP_PORT)
.build();
......@@ -171,9 +171,9 @@ public class PeerConnectivityManager {
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchTcpSrc((short) BgpConstants.BGP_PORT)
.build();
......@@ -191,9 +191,9 @@ public class PeerConnectivityManager {
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchTcpDst((short) BgpConstants.BGP_PORT)
.build();
......@@ -211,9 +211,9 @@ public class PeerConnectivityManager {
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchTcpSrc((short) BgpConstants.BGP_PORT)
.build();
......@@ -281,9 +281,9 @@ public class PeerConnectivityManager {
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_ICMP)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
......@@ -301,9 +301,9 @@ public class PeerConnectivityManager {
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_ICMP)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
IpPrefix.MAX_INET_MASK_LENGTH))
.build();
PointToPointIntent reversedIntent =
......
......@@ -75,7 +75,7 @@ public class RouteEntry {
StringBuilder result = new StringBuilder(ip4Prefix.prefixLength());
long value = ip4Prefix.toInt();
for (int i = 0; i < ip4Prefix.prefixLength(); i++) {
long mask = 1 << (IpAddress.MAX_INET_MASK - 1 - i);
long mask = 1 << (IpPrefix.MAX_INET_MASK_LENGTH - 1 - i);
result.append(((value & mask) == 0) ? "0" : "1");
}
return result.toString();
......
......@@ -190,12 +190,12 @@ class TestBgpPeerChannelHandler extends SimpleChannelHandler {
IpAddress address = prefix.toIpAddress();
long value = address.toInt() & 0xffffffffL;
for (int i = 0; i < IpAddress.INET_LEN; i++) {
for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) {
if (prefixBytelen-- == 0) {
break;
}
long nextByte =
(value >> ((IpAddress.INET_LEN - i - 1) * 8)) & 0xff;
(value >> ((IpAddress.INET_BYTE_LENGTH - i - 1) * 8)) & 0xff;
message.writeByte((int) nextByte);
}
}
......
......@@ -46,7 +46,6 @@ import org.onlab.onos.net.provider.ProviderId;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.util.Timer;
......@@ -212,7 +211,7 @@ public class HostMonitor implements TimerTask {
arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
.setProtocolType(ARP.PROTO_TYPE_IP)
.setProtocolAddressLength((byte) IpPrefix.INET_LEN)
.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH)
.setOpCode(ARP.OP_REQUEST);
arp.setSenderHardwareAddress(sourceMac.getAddress())
......
......@@ -56,7 +56,6 @@ import org.onlab.onos.net.proxyarp.ProxyArpService;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
......@@ -368,7 +367,7 @@ public class ProxyArpManager implements ProxyArpService {
arp.setProtocolType(ARP.PROTO_TYPE_IP);
arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
arp.setProtocolAddressLength((byte) IpPrefix.INET_LEN);
arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH);
arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
arp.setSenderHardwareAddress(srcMac.getAddress());
arp.setTargetHardwareAddress(request.getSourceMACAddress());
......
......@@ -534,7 +534,7 @@ public class ProxyArpManagerTest {
arp.setProtocolType(ARP.PROTO_TYPE_IP);
arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
arp.setProtocolAddressLength((byte) IpPrefix.INET_LEN);
arp.setProtocolAddressLength((byte) IpAddress.INET_BYTE_LENGTH);
arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
arp.setSenderHardwareAddress(srcMac.getAddress());
......
......@@ -171,7 +171,8 @@ public class FlowEntryBuilder {
builder.setIpDst(IpPrefix.valueOf(di.getInt(),
di.asCidrMaskLength()));
} else {
builder.setIpDst(IpPrefix.valueOf(di.getInt()));
builder.setIpDst(IpPrefix.valueOf(di.getInt(),
IpPrefix.MAX_INET_MASK_LENGTH));
}
break;
case SET_NW_SRC:
......@@ -181,7 +182,8 @@ public class FlowEntryBuilder {
builder.setIpSrc(IpPrefix.valueOf(si.getInt(),
si.asCidrMaskLength()));
} else {
builder.setIpSrc(IpPrefix.valueOf(si.getInt()));
builder.setIpSrc(IpPrefix.valueOf(si.getInt(),
IpPrefix.MAX_INET_MASK_LENGTH));
}
break;
case EXPERIMENTER:
......@@ -256,7 +258,7 @@ public class FlowEntryBuilder {
} else {
dip = IpPrefix.valueOf(
match.get(MatchField.IPV4_DST).getInt(),
IpPrefix.MAX_INET_MASK);
IpPrefix.MAX_INET_MASK_LENGTH);
}
builder.matchIPDst(dip);
......@@ -272,7 +274,7 @@ public class FlowEntryBuilder {
} else {
sip = IpPrefix.valueOf(
match.get(MatchField.IPV4_SRC).getInt(),
IpPrefix.MAX_INET_MASK);
IpPrefix.MAX_INET_MASK_LENGTH);
}
builder.matchIPSrc(sip);
......
......@@ -15,147 +15,76 @@
*/
package org.onlab.packet;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* A class representing an IPv4 address.
* <p/>
* TODO this class is a clone of IpPrefix and still needs to be modified to
* look more like an IpAddress.
*/
public final class IpAddress implements Comparable<IpAddress> {
// TODO a comparator for netmasks? E.g. for sorting by prefix match order.
//IP Versions
// IP Versions
public enum Version { INET, INET6 };
//lengths of address, in bytes
public static final int INET_LEN = 4;
public static final int INET6_LEN = 16;
// lengths of address, in bytes
public static final int INET_BYTE_LENGTH = 4;
public static final int INET_BIT_LENGTH = INET_BYTE_LENGTH * Byte.SIZE;
public static final int INET6_BYTE_LENGTH = 16;
public static final int INET6_BIT_LENGTH = INET6_BYTE_LENGTH * Byte.SIZE;
//maximum CIDR value
public static final int MAX_INET_MASK = 32;
//no mask (no network), e.g. a simple address
public static final int DEFAULT_MASK = 0;
private final Version version;
private final byte[] octets;
/**
* Default value indicating an unspecified address.
* Constructor for given IP address version and address octets.
*
* @param ver the IP address version
* @param octets the IP address octets
*/
static final byte[] ANY = new byte [] {0, 0, 0, 0};
protected Version version;
protected byte[] octets;
protected int netmask;
private IpAddress(Version ver, byte[] octets, int netmask) {
this.version = ver;
this.octets = Arrays.copyOf(octets, INET_LEN);
this.netmask = netmask;
}
private IpAddress(Version ver, byte[] octets) {
this.version = ver;
this.octets = Arrays.copyOf(octets, INET_LEN);
this.netmask = DEFAULT_MASK;
this.octets = Arrays.copyOf(octets, INET_BYTE_LENGTH);
}
/**
* Converts a byte array into an IP address.
*
* @param address a byte array
* @param address the IP address value stored in network byte order
* (i.e., the most significant byte first)
* @return an IP address
*/
public static IpAddress valueOf(byte [] address) {
public static IpAddress valueOf(byte[] address) {
return new IpAddress(Version.INET, address);
}
/**
* Converts a byte array into an IP address.
*
* @param address a byte array
* @param netmask the CIDR value subnet mask
* @return an IP address
*/
public static IpAddress valueOf(byte [] address, int netmask) {
return new IpAddress(Version.INET, address, netmask);
}
/**
* Helper to convert an integer into a byte array.
*
* @param address the integer to convert
* @return a byte array
*/
private static byte [] bytes(int address) {
byte [] bytes = new byte [INET_LEN];
for (int i = 0; i < INET_LEN; i++) {
bytes[i] = (byte) ((address >> (INET_LEN - (i + 1)) * 8) & 0xff);
}
return bytes;
}
/**
* Converts an integer into an IPv4 address.
*
* @param address an integer representing an IP value
* @param address an integer representing an IPv4 value
* @return an IP address
*/
public static IpAddress valueOf(int address) {
return new IpAddress(Version.INET, bytes(address));
}
/**
* Converts an integer into an IPv4 address.
*
* @param address an integer representing an IP value
* @param netmask the CIDR value subnet mask
* @return an IP address
*/
public static IpAddress valueOf(int address, int netmask) {
return new IpAddress(Version.INET, bytes(address), netmask);
byte[] bytes =
ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(address).array();
return new IpAddress(Version.INET, bytes);
}
/**
* Converts a dotted-decimal string (x.x.x.x) into an IPv4 address. The
* string can also be in CIDR (slash) notation. If the netmask is omitted,
* it will be set to DEFAULT_MASK (0).
* Converts a dotted-decimal string (x.x.x.x) into an IPv4 address.
*
* @param address a IP address in string form, e.g. "10.0.0.1", "10.0.0.1/24"
* @param address a IP address in string form, e.g. "10.0.0.1".
* @return an IP address
*/
public static IpAddress valueOf(String address) {
final String [] parts = address.split("\\/");
if (parts.length > 2) {
throw new IllegalArgumentException("Malformed IP address string; "
+ "Address must take form \"x.x.x.x\" or \"x.x.x.x/y\"");
}
int mask = DEFAULT_MASK;
if (parts.length == 2) {
mask = Integer.parseInt(parts[1]);
if (mask > MAX_INET_MASK) {
throw new IllegalArgumentException(
"Value of subnet mask cannot exceed "
+ MAX_INET_MASK);
}
}
final String [] net = parts[0].split("\\.");
if (net.length != INET_LEN) {
final String[] net = address.split("\\.");
if (net.length != INET_BYTE_LENGTH) {
throw new IllegalArgumentException("Malformed IP address string; "
+ "Address must have four decimal values separated by dots (.)");
}
final byte [] bytes = new byte[INET_LEN];
for (int i = 0; i < INET_LEN; i++) {
final byte[] bytes = new byte[INET_BYTE_LENGTH];
for (int i = 0; i < INET_BYTE_LENGTH; i++) {
bytes[i] = (byte) Short.parseShort(net[i], 10);
}
return new IpAddress(Version.INET, bytes, mask);
return new IpAddress(Version.INET, bytes);
}
/**
......@@ -173,16 +102,7 @@ public final class IpAddress implements Comparable<IpAddress> {
* @return a byte array
*/
public byte[] toOctets() {
return Arrays.copyOf(this.octets, INET_LEN);
}
/**
* Returns the IP address prefix length.
*
* @return prefix length
*/
public int prefixLength() {
return netmask;
return Arrays.copyOf(this.octets, INET_BYTE_LENGTH);
}
/**
......@@ -191,110 +111,8 @@ public final class IpAddress implements Comparable<IpAddress> {
* @return the IP address's value as an integer
*/
public int toInt() {
int val = 0;
for (int i = 0; i < octets.length; i++) {
val <<= 8;
val |= octets[i] & 0xff;
}
return val;
}
/**
* Converts the IP address to a /32 IP prefix.
*
* @return the new IP prefix
*/
public IpPrefix toPrefix() {
return IpPrefix.valueOf(octets, MAX_INET_MASK);
}
/**
* Helper for computing the mask value from CIDR.
*
* @return an integer bitmask
*/
private int mask() {
int shift = MAX_INET_MASK - this.netmask;
return ((Integer.MAX_VALUE >>> (shift - 1)) << shift);
}
/**
* Returns the subnet mask in IpAddress form. The netmask value for
* the returned IpAddress is 0, as the address itself is a mask.
*
* @return the subnet mask
*/
public IpAddress netmask() {
return new IpAddress(Version.INET, bytes(mask()));
}
/**
* Returns the network portion of this address as an IpAddress.
* The netmask of the returned IpAddress is the current mask. If this
* address doesn't have a mask, this returns an all-0 IpAddress.
*
* @return the network address or null
*/
public IpAddress network() {
if (netmask == DEFAULT_MASK) {
return new IpAddress(version, ANY, DEFAULT_MASK);
}
byte [] net = new byte [4];
byte [] mask = bytes(mask());
for (int i = 0; i < INET_LEN; i++) {
net[i] = (byte) (octets[i] & mask[i]);
}
return new IpAddress(version, net, netmask);
}
/**
* Returns the host portion of the IPAddress, as an IPAddress.
* The netmask of the returned IpAddress is the current mask. If this
* address doesn't have a mask, this returns a copy of the current
* address.
*
* @return the host address
*/
public IpAddress host() {
if (netmask == DEFAULT_MASK) {
new IpAddress(version, octets, netmask);
}
byte [] host = new byte [INET_LEN];
byte [] mask = bytes(mask());
for (int i = 0; i < INET_LEN; i++) {
host[i] = (byte) (octets[i] & ~mask[i]);
}
return new IpAddress(version, host, netmask);
}
public boolean isMasked() {
return mask() != 0;
}
/**
* Determines whether a given address is contained within this IpAddress'
* network.
*
* @param other another IP address that could be contained in this network
* @return true if the other IP address is contained in this address'
* network, otherwise false
*/
public boolean contains(IpAddress other) {
if (this.netmask <= other.netmask) {
// Special case where they're both /32 addresses
if (this.netmask == MAX_INET_MASK) {
return Arrays.equals(octets, other.octets);
}
// Mask the other address with our network mask
IpAddress otherMasked =
IpAddress.valueOf(other.octets, netmask).network();
return network().equals(otherMasked);
}
return false;
ByteBuffer bb = ByteBuffer.wrap(octets);
return bb.getInt();
}
@Override
......@@ -308,7 +126,6 @@ public final class IpAddress implements Comparable<IpAddress> {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + netmask;
result = prime * result + Arrays.hashCode(octets);
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
......@@ -326,9 +143,6 @@ public final class IpAddress implements Comparable<IpAddress> {
return false;
}
IpAddress other = (IpAddress) obj;
if (netmask != other.netmask) {
return false;
}
if (!Arrays.equals(octets, other.octets)) {
return false;
}
......@@ -341,8 +155,7 @@ public final class IpAddress implements Comparable<IpAddress> {
@Override
/*
* (non-Javadoc)
* format is "x.x.x.x" for non-masked (netmask 0) addresses,
* and "x.x.x.x/y" for masked addresses.
* format is "x.x.x.x" for IPv4 addresses.
*
* @see java.lang.Object#toString()
*/
......@@ -354,11 +167,6 @@ public final class IpAddress implements Comparable<IpAddress> {
}
builder.append(String.format("%d", b & 0xff));
}
if (netmask != DEFAULT_MASK) {
builder.append("/");
builder.append(String.format("%d", netmask));
}
return builder.toString();
}
}
......
......@@ -26,48 +26,37 @@ public final class IpPrefix {
// TODO a comparator for netmasks? E.g. for sorting by prefix match order.
//IP Versions
// IP Versions: IPv4 and IPv6
public enum Version { INET, INET6 };
//lengths of address, in bytes
public static final int INET_LEN = 4;
public static final int INET6_LEN = 16;
// Maximum network mask length
public static final int MAX_INET_MASK_LENGTH = IpAddress.INET_BIT_LENGTH;
public static final int MAX_INET6_MASK_LENGTH = IpAddress.INET6_BIT_LENGTH;
//maximum CIDR value
public static final int MAX_INET_MASK = 32;
//no mask (no network), e.g. a simple address
public static final int DEFAULT_MASK = 0;
private static final int DEFAULT_MASK = 0;
/**
* Default value indicating an unspecified address.
*/
static final byte[] ANY = new byte [] {0, 0, 0, 0};
private static final byte[] ANY = new byte[] {0, 0, 0, 0};
protected Version version;
protected byte[] octets;
protected int netmask;
private IpPrefix(Version ver, byte[] octets, int netmask) {
this.version = ver;
this.octets = Arrays.copyOf(octets, INET_LEN);
this.netmask = netmask;
}
private IpPrefix(Version ver, byte[] octets) {
this.version = ver;
this.octets = Arrays.copyOf(octets, INET_LEN);
this.netmask = DEFAULT_MASK;
}
private final Version version;
private final byte[] octets;
private final int netmask;
/**
* Converts a byte array into an IP address.
* Constructor for given IP address version, prefix address octets,
* and network mask length.
*
* @param address a byte array
* @return an IP address
* @param ver the IP address version
* @param octets the IP prefix address octets
* @param netmask the network mask length
*/
public static IpPrefix valueOf(byte [] address) {
return new IpPrefix(Version.INET, address);
private IpPrefix(Version ver, byte[] octets, int netmask) {
this.version = ver;
this.octets = Arrays.copyOf(octets, IpAddress.INET_BYTE_LENGTH);
this.netmask = netmask;
}
/**
......@@ -77,7 +66,7 @@ public final class IpPrefix {
* @param netmask the CIDR value subnet mask
* @return an IP address
*/
public static IpPrefix valueOf(byte [] address, int netmask) {
public static IpPrefix valueOf(byte[] address, int netmask) {
return new IpPrefix(Version.INET, address, netmask);
}
......@@ -87,10 +76,11 @@ public final class IpPrefix {
* @param address the integer to convert
* @return a byte array
*/
private static byte [] bytes(int address) {
byte [] bytes = new byte [INET_LEN];
for (int i = 0; i < INET_LEN; i++) {
bytes[i] = (byte) ((address >> (INET_LEN - (i + 1)) * 8) & 0xff);
private static byte[] bytes(int address) {
byte[] bytes = new byte [IpAddress.INET_BYTE_LENGTH];
for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) {
bytes[i] = (byte) ((address >> (IpAddress.INET_BYTE_LENGTH
- (i + 1)) * 8) & 0xff);
}
return bytes;
......@@ -100,16 +90,6 @@ public final class IpPrefix {
* Converts an integer into an IPv4 address.
*
* @param address an integer representing an IP value
* @return an IP address
*/
public static IpPrefix valueOf(int address) {
return new IpPrefix(Version.INET, bytes(address));
}
/**
* Converts an integer into an IPv4 address.
*
* @param address an integer representing an IP value
* @param netmask the CIDR value subnet mask
* @return an IP address
*/
......@@ -127,7 +107,7 @@ public final class IpPrefix {
*/
public static IpPrefix valueOf(String address) {
final String [] parts = address.split("\\/");
final String[] parts = address.split("\\/");
if (parts.length > 2) {
throw new IllegalArgumentException("Malformed IP address string; "
+ "Address must take form \"x.x.x.x\" or \"x.x.x.x/y\"");
......@@ -136,20 +116,20 @@ public final class IpPrefix {
int mask = DEFAULT_MASK;
if (parts.length == 2) {
mask = Integer.parseInt(parts[1]);
if (mask > MAX_INET_MASK) {
if (mask > MAX_INET_MASK_LENGTH) {
throw new IllegalArgumentException(
"Value of subnet mask cannot exceed "
+ MAX_INET_MASK);
+ MAX_INET_MASK_LENGTH);
}
}
final String [] net = parts[0].split("\\.");
if (net.length != INET_LEN) {
final String[] net = parts[0].split("\\.");
if (net.length != IpAddress.INET_BYTE_LENGTH) {
throw new IllegalArgumentException("Malformed IP address string; "
+ "Address must have four decimal values separated by dots (.)");
}
final byte [] bytes = new byte[INET_LEN];
for (int i = 0; i < INET_LEN; i++) {
final byte[] bytes = new byte[IpAddress.INET_BYTE_LENGTH];
for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) {
bytes[i] = (byte) Short.parseShort(net[i], 10);
}
return new IpPrefix(Version.INET, bytes, mask);
......@@ -170,7 +150,7 @@ public final class IpPrefix {
* @return a byte array
*/
public byte[] toOctets() {
return Arrays.copyOf(this.octets, INET_LEN);
return Arrays.copyOf(this.octets, IpAddress.INET_BYTE_LENGTH);
}
/**
......@@ -202,18 +182,17 @@ public final class IpPrefix {
* @return an integer bitmask
*/
private int mask() {
int shift = MAX_INET_MASK - this.netmask;
int shift = MAX_INET_MASK_LENGTH - this.netmask;
return ((Integer.MAX_VALUE >>> (shift - 1)) << shift);
}
/**
* Returns the subnet mask in IpAddress form. The netmask value for
* the returned IpAddress is 0, as the address itself is a mask.
* Returns the subnet mask in IpAddress form.
*
* @return the subnet mask
* @return the subnet mask as an IpAddress
*/
public IpPrefix netmask() {
return new IpPrefix(Version.INET, bytes(mask()));
public IpAddress netmask() {
return IpAddress.valueOf(mask());
}
/**
......@@ -228,9 +207,9 @@ public final class IpPrefix {
return new IpPrefix(version, ANY, DEFAULT_MASK);
}
byte [] net = new byte [4];
byte [] mask = bytes(mask());
for (int i = 0; i < INET_LEN; i++) {
byte[] net = new byte [4];
byte[] mask = bytes(mask());
for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) {
net[i] = (byte) (octets[i] & mask[i]);
}
return new IpPrefix(version, net, netmask);
......@@ -249,9 +228,9 @@ public final class IpPrefix {
new IpPrefix(version, octets, netmask);
}
byte [] host = new byte [INET_LEN];
byte [] mask = bytes(mask());
for (int i = 0; i < INET_LEN; i++) {
byte[] host = new byte [IpAddress.INET_BYTE_LENGTH];
byte[] mask = bytes(mask());
for (int i = 0; i < IpAddress.INET_BYTE_LENGTH; i++) {
host[i] = (byte) (octets[i] & ~mask[i]);
}
return new IpPrefix(version, host, netmask);
......@@ -283,7 +262,7 @@ public final class IpPrefix {
public boolean contains(IpPrefix other) {
if (this.netmask <= other.netmask) {
// Special case where they're both /32 addresses
if (this.netmask == MAX_INET_MASK) {
if (this.netmask == MAX_INET_MASK_LENGTH) {
return Arrays.equals(octets, other.octets);
}
......@@ -302,7 +281,7 @@ public final class IpPrefix {
IpPrefix meMasked = network();
IpPrefix otherMasked =
IpPrefix.valueOf(address.octets, netmask).network();
IpPrefix.valueOf(address.toOctets(), netmask).network();
return Arrays.equals(meMasked.octets, otherMasked.octets);
}
......@@ -364,5 +343,4 @@ public final class IpPrefix {
}
return builder.toString();
}
}
......
......@@ -32,15 +32,15 @@ public class IpPrefixTest {
private static final byte [] BYTES2 = new byte [] {0xa, 0x0, 0x0, 0xb};
private static final int INTVAL1 = 167772170;
private static final int INTVAL2 = 167772171;
private static final String STRVAL = "10.0.0.12";
private static final int MASK = 16;
private static final String STRVAL = "10.0.0.12/16";
private static final int MASK_LENGTH = 16;
@Test
public void testEquality() {
IpPrefix ip1 = IpPrefix.valueOf(BYTES1);
IpPrefix ip2 = IpPrefix.valueOf(INTVAL1);
IpPrefix ip3 = IpPrefix.valueOf(BYTES2);
IpPrefix ip4 = IpPrefix.valueOf(INTVAL2);
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip2 = IpPrefix.valueOf(INTVAL1, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip3 = IpPrefix.valueOf(BYTES2, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip4 = IpPrefix.valueOf(INTVAL2, IpPrefix.MAX_INET_MASK_LENGTH);
IpPrefix ip5 = IpPrefix.valueOf(STRVAL);
new EqualsTester().addEqualityGroup(ip1, ip2)
......@@ -49,21 +49,21 @@ public class IpPrefixTest {
.testEquals();
// string conversions
IpPrefix ip6 = IpPrefix.valueOf(BYTES1, MASK);
IpPrefix ip6 = IpPrefix.valueOf(BYTES1, MASK_LENGTH);
IpPrefix ip7 = IpPrefix.valueOf("10.0.0.10/16");
IpPrefix ip8 = IpPrefix.valueOf(new byte [] {0xa, 0x0, 0x0, 0xc});
IpPrefix ip8 = IpPrefix.valueOf(new byte [] {0xa, 0x0, 0x0, 0xc}, 16);
assertEquals("incorrect address conversion", ip6, ip7);
assertEquals("incorrect address conversion", ip5, ip8);
}
@Test
public void basics() {
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK);
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH);
final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0xa};
//check fields
assertEquals("incorrect IP Version", Version.INET, ip1.version());
assertEquals("incorrect netmask", 16, ip1.netmask);
assertEquals("incorrect netmask", 16, ip1.prefixLength());
assertTrue("faulty toOctets()", Arrays.equals(bytes, ip1.toOctets()));
assertEquals("faulty toInt()", INTVAL1, ip1.toInt());
assertEquals("faulty toString()", "10.0.0.10/16", ip1.toString());
......@@ -72,7 +72,7 @@ public class IpPrefixTest {
@Test
public void netmasks() {
// masked
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK);
IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH);
IpPrefix host = IpPrefix.valueOf("0.0.0.10/16");
IpPrefix network = IpPrefix.valueOf("10.0.0.0/16");
......@@ -80,14 +80,6 @@ public class IpPrefixTest {
assertEquals("incorrect network address", network, ip1.network());
assertEquals("incorrect netmask", "255.255.0.0", ip1.netmask().toString());
//unmasked
IpPrefix ip2 = IpPrefix.valueOf(BYTES1);
IpPrefix umhost = IpPrefix.valueOf("10.0.0.10/0");
IpPrefix umnet = IpPrefix.valueOf("0.0.0.0/0");
assertEquals("incorrect host address", umhost, ip2.host());
assertEquals("incorrect host address", umnet, ip2.network());
assertTrue("incorrect netmask",
Arrays.equals(IpPrefix.ANY, ip2.netmask().toOctets()));
}
@Test
......