diff options
author | CNlucius <lukai1@huawei.com> | 2016-09-13 11:40:12 +0800 |
---|---|---|
committer | CNlucius <lukai1@huawei.com> | 2016-09-13 11:41:53 +0800 |
commit | b731e2f1dd0972409b136aebc7b463dd72c9cfad (patch) | |
tree | 5107d7d80c19ad8076c2c97c2b5ef8d1cf3ab903 /framework/src/onos/utils/misc/src/main/java/org/onlab/packet/IpAddress.java | |
parent | ee93993458266114c29271a481ef9ce7ce621b2a (diff) |
ONOSFW-171
O/S-SFC-ONOS scenario documentation
Change-Id: I51ae1cf736ea24ab6680f8edca1b2bf5dd598365
Signed-off-by: CNlucius <lukai1@huawei.com>
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.java | 559 |
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(); - } -} |