blob: ecddc3a5f630d31b14ff2496041b64c84fb1b194 [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 /**
Charles Chan1cf4ca32017-05-09 10:33:04 -070048 * All-zero unspecified IPv6 address.
49 */
50 public static final Ip6Address ZERO = Ip6Address.valueOf("::");
51
52 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080053 * Constructor for given IP address version and address octets.
54 *
55 * @param value the IP address value stored in network byte order
56 * (i.e., the most significant byte first)
57 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070058 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080059 private Ip6Address(byte[] value) {
60 super(VERSION, value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070061 }
62
63 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080064 * Converts a byte array into an IPv6 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070065 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080066 * @param value the IPv6 address value stored in network byte order
67 * (i.e., the most significant byte first)
68 * @return an IPv6 address
69 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070070 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080071 public static Ip6Address valueOf(byte[] value) {
72 return new Ip6Address(value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070073 }
74
75 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080076 * Converts a byte array and a given offset from the beginning of the
77 * array into an IPv6 address.
78 * <p>
79 * The IP address is stored in network byte order (i.e., the most
80 * significant byte first).
81 * </p>
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070082 * @param value the value to use
83 * @param offset the offset in bytes from the beginning of the byte array
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080084 * @return an IPv6 address
85 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070086 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080087 public static Ip6Address valueOf(byte[] value, int offset) {
88 IpAddress.checkArguments(VERSION, value, offset);
89 byte[] bc = Arrays.copyOfRange(value, offset, value.length);
90 return Ip6Address.valueOf(bc);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070091 }
92
93 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080094 * Converts an InetAddress into an IPv6 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070095 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080096 * @param inetAddress the InetAddress value to use. It must contain an IPv6
97 * address
98 * @return an IPv6 address
99 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700100 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800101 public static Ip6Address valueOf(InetAddress inetAddress) {
102 byte[] bytes = inetAddress.getAddress();
103 if (inetAddress instanceof Inet6Address) {
104 return new Ip6Address(bytes);
105 }
106 if ((inetAddress instanceof Inet4Address) ||
107 (bytes.length == INET_BYTE_LENGTH)) {
108 final String msg = "Invalid IPv6 version address string: " +
109 inetAddress.toString();
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700110 throw new IllegalArgumentException(msg);
111 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800112 // Use the number of bytes as a hint
113 if (bytes.length == INET6_BYTE_LENGTH) {
114 return new Ip6Address(bytes);
115 }
116 final String msg = "Unrecognized IP version address string: " +
117 inetAddress.toString();
118 throw new IllegalArgumentException(msg);
119 }
120
121 /**
122 * Converts an IPv6 string literal (e.g., "1111:2222::8888") into an IP
123 * address.
124 *
125 * @param value an IPv6 address value in string form
126 * @return an IPv6 address
127 * @throws IllegalArgumentException if the argument is invalid
128 */
129 public static Ip6Address valueOf(String value) {
130 InetAddress inetAddress = null;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700131 try {
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800132 inetAddress = InetAddresses.forString(value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700133 } catch (IllegalArgumentException e) {
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800134 final String msg = "Invalid IP address string: " + value;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700135 throw new IllegalArgumentException(msg);
136 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800137 return valueOf(inetAddress);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700138 }
139
140 /**
141 * Creates an IPv6 network mask prefix.
142 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800143 * @param prefixLength the length of the mask prefix. Must be in the
144 * interval [0, 128]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700145 * @return a new IPv6 address that contains a mask prefix of the
146 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800147 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700148 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800149 public static Ip6Address makeMaskPrefix(int prefixLength) {
150 byte[] mask = IpAddress.makeMaskPrefixArray(VERSION, prefixLength);
151 return new Ip6Address(mask);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700152 }
153
154 /**
155 * Creates an IPv6 address by masking it with a network mask of given
156 * mask length.
157 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800158 * @param address the address to mask
159 * @param prefixLength the length of the mask prefix. Must be in the
160 * interval [0, 128]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700161 * @return a new IPv6 address that is masked with a mask prefix of the
162 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800163 * @throws IllegalArgumentException if the prefix length is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700164 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800165 public static Ip6Address makeMaskedAddress(final Ip6Address address,
166 int prefixLength) {
167 byte[] net = makeMaskedAddressArray(address, prefixLength);
168 return Ip6Address.valueOf(net);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700169 }
170}