blob: 085ecfc90ab7c8679500e22c1d55bec36424df40 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
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 /**
Yi Tseng525ff402017-10-23 19:39:39 -070035 * A link-scoped multicast address used by a DHCP client to communicate with
36 * neighboring DHCP relay agents and servers. (RFC 3315)
37 */
38 public static final Ip6Address ALL_DHCP_RELAY_AGENTS_AND_SERVERS =
39 Ip6Address.valueOf("ff02::1:2");
40 /**
41 * A site-scoped multicast address used by a DHCP relay agent to
42 * communicate with DHCP servers. (RFC 3315)
43 */
44 public static final Ip6Address ALL_DHCP_SERVERS =
45 Ip6Address.valueOf("ff05::1:3");
46
47 /**
shalde064280feec2018-06-15 19:01:29 -040048 * All RIP routers multicast group. (RFC 2080)
49 */
50 public static final Ip6Address ALL_RIP_ROUTERS =
51 Ip6Address.valueOf("ff02::9");
52
53 /**
Charles Chan1cf4ca32017-05-09 10:33:04 -070054 * All-zero unspecified IPv6 address.
55 */
56 public static final Ip6Address ZERO = Ip6Address.valueOf("::");
57
58 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080059 * Constructor for given IP address version and address octets.
60 *
61 * @param value the IP address value stored in network byte order
62 * (i.e., the most significant byte first)
63 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070064 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080065 private Ip6Address(byte[] value) {
66 super(VERSION, value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070067 }
68
69 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080070 * Converts a byte array into an IPv6 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070071 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080072 * @param value the IPv6 address value stored in network byte order
73 * (i.e., the most significant byte first)
74 * @return an IPv6 address
75 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070076 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080077 public static Ip6Address valueOf(byte[] value) {
78 return new Ip6Address(value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070079 }
80
81 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080082 * Converts a byte array and a given offset from the beginning of the
83 * array into an IPv6 address.
84 * <p>
85 * The IP address is stored in network byte order (i.e., the most
86 * significant byte first).
87 * </p>
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070088 * @param value the value to use
89 * @param offset the offset in bytes from the beginning of the byte array
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080090 * @return an IPv6 address
91 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070092 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080093 public static Ip6Address valueOf(byte[] value, int offset) {
94 IpAddress.checkArguments(VERSION, value, offset);
95 byte[] bc = Arrays.copyOfRange(value, offset, value.length);
96 return Ip6Address.valueOf(bc);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070097 }
98
99 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800100 * Converts an InetAddress into an IPv6 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700101 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800102 * @param inetAddress the InetAddress value to use. It must contain an IPv6
103 * address
104 * @return an IPv6 address
105 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700106 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800107 public static Ip6Address valueOf(InetAddress inetAddress) {
108 byte[] bytes = inetAddress.getAddress();
109 if (inetAddress instanceof Inet6Address) {
110 return new Ip6Address(bytes);
111 }
112 if ((inetAddress instanceof Inet4Address) ||
113 (bytes.length == INET_BYTE_LENGTH)) {
114 final String msg = "Invalid IPv6 version address string: " +
115 inetAddress.toString();
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700116 throw new IllegalArgumentException(msg);
117 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800118 // Use the number of bytes as a hint
119 if (bytes.length == INET6_BYTE_LENGTH) {
120 return new Ip6Address(bytes);
121 }
122 final String msg = "Unrecognized IP version address string: " +
123 inetAddress.toString();
124 throw new IllegalArgumentException(msg);
125 }
126
127 /**
128 * Converts an IPv6 string literal (e.g., "1111:2222::8888") into an IP
129 * address.
130 *
131 * @param value an IPv6 address value in string form
132 * @return an IPv6 address
133 * @throws IllegalArgumentException if the argument is invalid
134 */
135 public static Ip6Address valueOf(String value) {
136 InetAddress inetAddress = null;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700137 try {
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800138 inetAddress = InetAddresses.forString(value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700139 } catch (IllegalArgumentException e) {
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800140 final String msg = "Invalid IP address string: " + value;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700141 throw new IllegalArgumentException(msg);
142 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800143 return valueOf(inetAddress);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700144 }
145
146 /**
147 * Creates an IPv6 network mask prefix.
148 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800149 * @param prefixLength the length of the mask prefix. Must be in the
150 * interval [0, 128]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700151 * @return a new IPv6 address that contains a mask prefix of the
152 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800153 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700154 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800155 public static Ip6Address makeMaskPrefix(int prefixLength) {
156 byte[] mask = IpAddress.makeMaskPrefixArray(VERSION, prefixLength);
157 return new Ip6Address(mask);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700158 }
159
160 /**
161 * Creates an IPv6 address by masking it with a network mask of given
162 * mask length.
163 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800164 * @param address the address to mask
165 * @param prefixLength the length of the mask prefix. Must be in the
166 * interval [0, 128]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700167 * @return a new IPv6 address that is masked with a mask prefix of the
168 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800169 * @throws IllegalArgumentException if the prefix length is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700170 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800171 public static Ip6Address makeMaskedAddress(final Ip6Address address,
172 int prefixLength) {
173 byte[] net = makeMaskedAddressArray(address, prefixLength);
174 return Ip6Address.valueOf(net);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700175 }
176}