aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java')
-rw-r--r--framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java559
1 files changed, 0 insertions, 559 deletions
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
deleted file mode 100644
index 5fdd3276..00000000
--- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onlab.packet;
-
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Objects;
-import com.google.common.net.InetAddresses;
-import com.google.common.primitives.UnsignedBytes;
-
-
-/**
- * A class representing an IP address.
- * This class is immutable.
- */
-public class IpAddress implements Comparable<IpAddress> {
- private static final int BIT_MASK = 0x000000ff;
-
- // IP Versions
- public enum Version { INET, INET6 };
-
- // 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;
-
- private final Version version;
- private final byte[] octets;
-
- /**
- * Constructor for given IP address version and address octets.
- *
- * @param version the IP address version
- * @param value the IP address value stored in network byte order
- * (i.e., the most significant byte first)
- * @throws IllegalArgumentException if the arguments are invalid
- */
- protected IpAddress(Version version, byte[] value) {
- checkArguments(version, value, 0);
- this.version = version;
- switch (version) {
- case INET:
- this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH);
- break;
- case INET6:
- this.octets = Arrays.copyOf(value, INET6_BYTE_LENGTH);
- break;
- default:
- // Should not be reached
- this.octets = null;
- break;
- }
- }
-
- /**
- * Returns the IP version of this address.
- *
- * @return the version
- */
- public Version version() {
- return this.version;
- }
-
- /**
- * Tests whether the IP version of this address is IPv4.
- *
- * @return true if the IP version of this address is IPv4, otherwise false.
- */
- public boolean isIp4() {
- return (version() == Ip4Address.VERSION);
- }
-
- /**
- * Tests whether the IP version of this address is IPv6.
- *
- * @return true if the IP version of this address is IPv6, otherwise false.
- */
- public boolean isIp6() {
- return (version() == Ip6Address.VERSION);
- }
-
- /**
- * Gets the {@link Ip4Address} view of the IP address.
- *
- * @return the {@link Ip4Address} view of the IP address if it is IPv4,
- * otherwise null
- */
- public Ip4Address getIp4Address() {
- if (!isIp4()) {
- return null;
- }
-
- // Return this object itself if it is already instance of Ip4Address
- if (this instanceof Ip4Address) {
- return (Ip4Address) this;
- }
- return Ip4Address.valueOf(octets);
- }
-
- /**
- * Gets the {@link Ip6Address} view of the IP address.
- *
- * @return the {@link Ip6Address} view of the IP address if it is IPv6,
- * otherwise null
- */
- public Ip6Address getIp6Address() {
- if (!isIp6()) {
- return null;
- }
-
- // Return this object itself if it is already instance of Ip6Address
- if (this instanceof Ip6Address) {
- return (Ip6Address) this;
- }
- return Ip6Address.valueOf(octets);
- }
-
- /**
- * Returns the IP address as a byte array.
- *
- * @return a byte array
- */
- public byte[] toOctets() {
- return Arrays.copyOf(octets, octets.length);
- }
-
- /**
- * Computes the IP address byte length for a given IP version.
- *
- * @param version the IP version
- * @return the IP address byte length for the IP version
- * @throws IllegalArgumentException if the IP version is invalid
- */
- public static int byteLength(Version version) {
- switch (version) {
- case INET:
- return INET_BYTE_LENGTH;
- case INET6:
- return INET6_BYTE_LENGTH;
- default:
- String msg = "Invalid IP version " + version;
- throw new IllegalArgumentException(msg);
- }
- }
-
- /**
- * Converts an integer into an IPv4 address.
- *
- * @param value an integer representing an IPv4 address value
- * @return an IP address
- */
- public static IpAddress valueOf(int value) {
- byte[] bytes =
- ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(value).array();
- return new IpAddress(Version.INET, bytes);
- }
-
- /**
- * Converts a byte array into an IP address.
- *
- * @param version the IP address version
- * @param value the IP address value stored in network byte order
- * (i.e., the most significant byte first)
- * @return an IP address
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static IpAddress valueOf(Version version, byte[] value) {
- return new IpAddress(version, value);
- }
-
- /**
- * Converts a byte array and a given offset from the beginning of the
- * array into an IP address.
- * <p>
- * The IP address is stored in network byte order (i.e., the most
- * significant byte first).
- * </p>
- * @param version the IP address version
- * @param value the value to use
- * @param offset the offset in bytes from the beginning of the byte array
- * @return an IP address
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static IpAddress valueOf(Version version, byte[] value,
- int offset) {
- checkArguments(version, value, offset);
- byte[] bc = Arrays.copyOfRange(value, offset, value.length);
- return IpAddress.valueOf(version, bc);
- }
-
- /**
- * Converts an InetAddress into an IP address.
- *
- * @param inetAddress the InetAddress value to use
- * @return an IP address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static IpAddress valueOf(InetAddress inetAddress) {
- byte[] bytes = inetAddress.getAddress();
- if (inetAddress instanceof Inet4Address) {
- return new IpAddress(Version.INET, bytes);
- }
- if (inetAddress instanceof Inet6Address) {
- return new IpAddress(Version.INET6, bytes);
- }
- // Use the number of bytes as a hint
- if (bytes.length == INET_BYTE_LENGTH) {
- return new IpAddress(Version.INET, bytes);
- }
- if (bytes.length == INET6_BYTE_LENGTH) {
- return new IpAddress(Version.INET6, bytes);
- }
- final String msg = "Unrecognized IP version address string: " +
- inetAddress.toString();
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Converts an IPv4 or IPv6 string literal (e.g., "10.2.3.4" or
- * "1111:2222::8888") into an IP address.
- *
- * @param value an IP address value in string form
- * @return an IP address
- * @throws IllegalArgumentException if the argument is invalid
- */
- public static IpAddress valueOf(String value) {
- InetAddress inetAddress = null;
- try {
- inetAddress = InetAddresses.forString(value);
- } catch (IllegalArgumentException e) {
- final String msg = "Invalid IP address string: " + value;
- throw new IllegalArgumentException(msg);
- }
- return valueOf(inetAddress);
- }
-
- /**
- * Creates an IP network mask prefix.
- *
- * @param version the IP address version
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a new IP address that contains a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the arguments are invalid
- */
- public static IpAddress makeMaskPrefix(Version version, int prefixLength) {
- byte[] mask = makeMaskPrefixArray(version, prefixLength);
- return new IpAddress(version, mask);
- }
-
- /**
- * Creates an IP address by masking it with a network mask of given
- * mask length.
- *
- * @param address the address to mask
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a new IP address that is masked with a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the prefix length is invalid
- */
- public static IpAddress makeMaskedAddress(final IpAddress address,
- int prefixLength) {
- if (address instanceof Ip4Address) {
- Ip4Address ip4a = (Ip4Address) address;
- return Ip4Address.makeMaskedAddress(ip4a, prefixLength);
- } else if (address instanceof Ip6Address) {
- Ip6Address ip6a = (Ip6Address) address;
- return Ip6Address.makeMaskedAddress(ip6a, prefixLength);
- } else {
- byte[] net = makeMaskedAddressArray(address, prefixLength);
- return IpAddress.valueOf(address.version(), net);
- }
- }
-
- /**
- * Check if this IP address is zero.
- *
- * @return true if this address is zero
- */
- public boolean isZero() {
- for (byte b : octets) {
- if (b != 0) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Check if this IP address is self-assigned.
- *
- * @return true if this address is self-assigned
- */
- public boolean isSelfAssigned() {
- return isIp4() && octets[0] == (byte) 169;
- }
-
- @Override
- public int compareTo(IpAddress o) {
- // Compare first the version
- if (this.version != o.version) {
- return this.version.compareTo(o.version);
- }
-
- // Compare the bytes, one-by-one
- for (int i = 0; i < this.octets.length; i++) {
- if (this.octets[i] != o.octets[i]) {
- return UnsignedBytes.compare(this.octets[i], o.octets[i]);
- }
- }
- return 0; // Equal
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(version, Arrays.hashCode(octets));
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if ((obj == null) || (!(obj instanceof IpAddress))) {
- return false;
- }
- IpAddress other = (IpAddress) obj;
- return (version == other.version) &&
- Arrays.equals(octets, other.octets);
- }
-
- @Override
- /*
- * (non-Javadoc)
- * The string representation of the IP address: "x.x.x.x" for IPv4
- * addresses, or ':' separated string for IPv6 addresses.
- *
- * @see java.lang.Object#toString()
- */
- public String toString() {
- // FIXME InetAddress is super slow
- switch (version) {
- case INET:
- return String.format("%d.%d.%d.%d", octets[0] & 0xff,
- octets[1] & 0xff,
- octets[2] & 0xff,
- octets[3] & 0xff);
- case INET6:
- default:
- return ipv6ToStringHelper();
- }
- }
-
- /**
- * Generates an IP prefix.
- *
- * @return the IP prefix of the IP address
- */
- public IpPrefix toIpPrefix() {
-
- if (isIp4()) {
- return IpPrefix.valueOf(new IpAddress(Version.INET, octets),
- Ip4Address.BIT_LENGTH);
- } else {
- return IpPrefix.valueOf(new IpAddress(Version.INET6, octets),
- Ip6Address.BIT_LENGTH);
- }
- }
-
- /**
- * Gets the IP address name for the IP address version.
- *
- * @param version the IP address version
- * @return the IP address name for the IP address version
- */
- private static String addressName(Version version) {
- switch (version) {
- case INET:
- return "IPv4";
- case INET6:
- return "IPv6";
- default:
- break;
- }
- return "UnknownIP(" + version + ")";
- }
-
- /**
- * Checks whether the arguments are valid.
- *
- * @param version the IP address version
- * @param value the IP address value stored in a byte array
- * @param offset the offset in bytes from the beginning of the byte
- * array with the address
- * @throws IllegalArgumentException if any of the arguments is invalid
- */
- static void checkArguments(Version version, byte[] value, int offset) {
- // Check the offset and byte array length
- int addrByteLength = byteLength(version);
- if ((offset < 0) || (offset + addrByteLength > value.length)) {
- String msg;
- if (value.length < addrByteLength) {
- msg = "Invalid " + addressName(version) +
- " address array: array length: " + value.length +
- ". Must be at least " + addrByteLength;
- } else {
- msg = "Invalid " + addressName(version) +
- " address array: array offset: " + offset +
- ". Must be in the interval [0, " +
- (value.length - addrByteLength) + "]";
- }
- throw new IllegalArgumentException(msg);
- }
- }
-
- /**
- * Creates a byte array for IP network mask prefix.
- *
- * @param version the IP address version
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a byte array that contains a mask prefix of the
- * specified length
- * @throws IllegalArgumentException if the arguments are invalid
- */
- static byte[] makeMaskPrefixArray(Version version, int prefixLength) {
- int addrByteLength = byteLength(version);
- int addrBitLength = addrByteLength * Byte.SIZE;
-
- // Verify the prefix length
- if ((prefixLength < 0) || (prefixLength > addrBitLength)) {
- final String msg = "Invalid IP prefix length: " + prefixLength +
- ". Must be in the interval [0, " + addrBitLength + "].";
- throw new IllegalArgumentException(msg);
- }
-
- // Number of bytes and extra bits that should be all 1s
- int maskBytes = prefixLength / Byte.SIZE;
- int maskBits = prefixLength % Byte.SIZE;
- byte[] mask = new byte[addrByteLength];
-
- // Set the bytes and extra bits to 1s
- for (int i = 0; i < maskBytes; i++) {
- mask[i] = (byte) 0xff; // Set mask bytes to 1s
- }
- for (int i = maskBytes; i < addrByteLength; i++) {
- mask[i] = 0; // Set remaining bytes to 0s
- }
- if (maskBits > 0) {
- mask[maskBytes] = (byte) (0xff << (Byte.SIZE - maskBits));
- }
- return mask;
- }
-
- /**
- * Creates a byte array that represents an IP address masked with
- * a network mask of given mask length.
- *
- * @param addr the address to mask
- * @param prefixLength the length of the mask prefix. Must be in the
- * interval [0, 32] for IPv4, or [0, 128] for IPv6
- * @return a byte array that represents the IP address masked with
- * a mask prefix of the specified length
- * @throws IllegalArgumentException if the prefix length is invalid
- */
- static byte[] makeMaskedAddressArray(final IpAddress addr,
- int prefixLength) {
- byte[] mask = IpAddress.makeMaskPrefixArray(addr.version(),
- prefixLength);
- byte[] net = new byte[mask.length];
-
- // Mask each byte
- for (int i = 0; i < net.length; i++) {
- net[i] = (byte) (addr.octets[i] & mask[i]);
- }
- return net;
- }
-
- /**
- * Creates a string based on the IPv6 recommendations for canonical representations found here:
- * https://tools.ietf.org/html/rfc5952#section-1.
- * @return A properly formatted IPv6 canonical representation.
- */
- private String ipv6ToStringHelper() {
- //Populate a buffer with the string of the full address with leading zeros stripped
- StringBuffer buff = new StringBuffer();
- buff.append(String.format("%x:%x:%x:%x:%x:%x:%x:%x",
- (((octets[0] & BIT_MASK) << 8) | (octets[1] & BIT_MASK)),
- (((octets[2] & BIT_MASK) << 8) | (octets[3] & BIT_MASK)),
- (((octets[4] & BIT_MASK) << 8) | (octets[5] & BIT_MASK)),
- (((octets[6] & BIT_MASK) << 8) | (octets[7] & BIT_MASK)),
- (((octets[8] & BIT_MASK) << 8) | (octets[9] & BIT_MASK)),
- (((octets[10] & BIT_MASK) << 8) | (octets[11] & BIT_MASK)),
- (((octets[12] & BIT_MASK) << 8) | (octets[13] & BIT_MASK)),
- (((octets[14] & BIT_MASK) << 8) | (octets[15] & BIT_MASK))));
- //Initialize variables for tracking longest zero subsequence, tiebreaking by first occurence
- int longestSeqStart, longestSeqLen, currSeqStart, currSeqLen;
- longestSeqStart = 0;
- longestSeqLen = 0;
- currSeqStart = 0;
- currSeqLen = 0;
-
- for (int index = 0; index < buff.length(); index++) {
- if (buff.charAt(index) == ':') {
- if (currSeqLen != 0 && buff.charAt(index + 1) == '0') {
- currSeqLen += 1;
- }
- } else if (buff.charAt(index) == '0' && ((index == 0) || (buff.charAt(index - 1) == ':'))) {
- if (currSeqLen == 0) {
- currSeqStart = index;
- }
- currSeqLen += 1;
- } else {
- if (currSeqLen > longestSeqLen) {
- longestSeqStart = currSeqStart;
- longestSeqLen = currSeqLen;
- }
- currSeqLen = 0;
- }
- }
-
- if (currSeqLen > longestSeqLen) {
- longestSeqLen = currSeqLen;
- longestSeqStart = currSeqStart;
- }
- if (longestSeqLen > 1) {
- if (buff.length() == (longestSeqStart + longestSeqLen)) {
- buff.append(':');
- }
-
- buff.delete(longestSeqStart, longestSeqStart + longestSeqLen);
-
- if (longestSeqStart == 0) {
- buff.insert(0, ':');
- }
- }
-
- return buff.toString();
- }
-}