blob: 046920a2b2544ffb78fcef0b304e085468c480ec [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070016package org.onlab.packet;
17
18import java.net.InetAddress;
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080019import java.net.Inet4Address;
20import java.net.Inet6Address;
21import java.util.Arrays;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070022
23import com.google.common.net.InetAddresses;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070024
25/**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080026 * A class representing an IPv6 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070027 * This class is immutable.
28 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080029public final class Ip6Address extends IpAddress {
30 public static final IpAddress.Version VERSION = IpAddress.Version.INET6;
31 public static final int BYTE_LENGTH = IpAddress.INET6_BYTE_LENGTH;
32 public static final int BIT_LENGTH = IpAddress.INET6_BIT_LENGTH;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070033
34 /**
Charles Chan1cf4ca32017-05-09 10:33:04 -070035 * All-zero unspecified IPv6 address.
36 */
37 public static final Ip6Address ZERO = Ip6Address.valueOf("::");
38
39 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080040 * Constructor for given IP address version and address octets.
41 *
42 * @param value the IP address value stored in network byte order
43 * (i.e., the most significant byte first)
44 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070045 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080046 private Ip6Address(byte[] value) {
47 super(VERSION, value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070048 }
49
50 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080051 * Converts a byte array into an IPv6 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070052 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080053 * @param value the IPv6 address value stored in network byte order
54 * (i.e., the most significant byte first)
55 * @return an IPv6 address
56 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070057 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080058 public static Ip6Address valueOf(byte[] value) {
59 return new Ip6Address(value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070060 }
61
62 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080063 * Converts a byte array and a given offset from the beginning of the
64 * array into an IPv6 address.
65 * <p>
66 * The IP address is stored in network byte order (i.e., the most
67 * significant byte first).
68 * </p>
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070069 * @param value the value to use
70 * @param offset the offset in bytes from the beginning of the byte array
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080071 * @return an IPv6 address
72 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070073 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080074 public static Ip6Address valueOf(byte[] value, int offset) {
75 IpAddress.checkArguments(VERSION, value, offset);
76 byte[] bc = Arrays.copyOfRange(value, offset, value.length);
77 return Ip6Address.valueOf(bc);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070078 }
79
80 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080081 * Converts an InetAddress into an IPv6 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070082 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080083 * @param inetAddress the InetAddress value to use. It must contain an IPv6
84 * address
85 * @return an IPv6 address
86 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070087 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080088 public static Ip6Address valueOf(InetAddress inetAddress) {
89 byte[] bytes = inetAddress.getAddress();
90 if (inetAddress instanceof Inet6Address) {
91 return new Ip6Address(bytes);
92 }
93 if ((inetAddress instanceof Inet4Address) ||
94 (bytes.length == INET_BYTE_LENGTH)) {
95 final String msg = "Invalid IPv6 version address string: " +
96 inetAddress.toString();
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070097 throw new IllegalArgumentException(msg);
98 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080099 // Use the number of bytes as a hint
100 if (bytes.length == INET6_BYTE_LENGTH) {
101 return new Ip6Address(bytes);
102 }
103 final String msg = "Unrecognized IP version address string: " +
104 inetAddress.toString();
105 throw new IllegalArgumentException(msg);
106 }
107
108 /**
109 * Converts an IPv6 string literal (e.g., "1111:2222::8888") into an IP
110 * address.
111 *
112 * @param value an IPv6 address value in string form
113 * @return an IPv6 address
114 * @throws IllegalArgumentException if the argument is invalid
115 */
116 public static Ip6Address valueOf(String value) {
117 InetAddress inetAddress = null;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700118 try {
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800119 inetAddress = InetAddresses.forString(value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700120 } catch (IllegalArgumentException e) {
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800121 final String msg = "Invalid IP address string: " + value;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700122 throw new IllegalArgumentException(msg);
123 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800124 return valueOf(inetAddress);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700125 }
126
127 /**
128 * Creates an IPv6 network mask prefix.
129 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800130 * @param prefixLength the length of the mask prefix. Must be in the
131 * interval [0, 128]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700132 * @return a new IPv6 address that contains a mask prefix of the
133 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800134 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700135 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800136 public static Ip6Address makeMaskPrefix(int prefixLength) {
137 byte[] mask = IpAddress.makeMaskPrefixArray(VERSION, prefixLength);
138 return new Ip6Address(mask);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700139 }
140
141 /**
142 * Creates an IPv6 address by masking it with a network mask of given
143 * mask length.
144 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800145 * @param address the address to mask
146 * @param prefixLength the length of the mask prefix. Must be in the
147 * interval [0, 128]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700148 * @return a new IPv6 address that is masked with a mask prefix of the
149 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800150 * @throws IllegalArgumentException if the prefix length is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700151 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800152 public static Ip6Address makeMaskedAddress(final Ip6Address address,
153 int prefixLength) {
154 byte[] net = makeMaskedAddressArray(address, prefixLength);
155 return Ip6Address.valueOf(net);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700156 }
157}