blob: 50472716fccc7db23b8bcc47d62e60412309a37d [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
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080018import java.net.InetAddress;
19import java.net.Inet4Address;
20import java.net.Inet6Address;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070021import java.nio.ByteBuffer;
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080022import java.util.Arrays;
23
24import com.google.common.net.InetAddresses;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070025
26/**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080027 * A class representing an IPv4 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070028 * This class is immutable.
29 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080030public final class Ip4Address extends IpAddress {
31 public static final IpAddress.Version VERSION = IpAddress.Version.INET;
32 public static final int BYTE_LENGTH = IpAddress.INET_BYTE_LENGTH;
33 public static final int BIT_LENGTH = IpAddress.INET_BIT_LENGTH;
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070034
35 /**
Charles Chan1cf4ca32017-05-09 10:33:04 -070036 * All-zero unspecified IPv4 address.
37 */
38 public static final Ip4Address ZERO = Ip4Address.valueOf("0.0.0.0");
39
40 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080041 * Constructor for given IP address version and address octets.
42 *
43 * @param value the IP address value stored in network byte order
44 * (i.e., the most significant byte first)
45 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070046 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080047 private Ip4Address(byte[] value) {
48 super(VERSION, value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070049 }
50
51 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080052 * Returns the integer value of this IPv4 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070053 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080054 * @return the IPv4 address's value as an integer
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070055 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080056 public int toInt() {
57 ByteBuffer bb = ByteBuffer.wrap(super.toOctets());
58 return bb.getInt();
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070059 }
60
61 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080062 * Converts an integer into an IPv4 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070063 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080064 * @param value an integer representing an IPv4 address value
65 * @return an IPv4 address
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070066 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080067 public static Ip4Address valueOf(int value) {
68 byte[] bytes =
69 ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(value).array();
70 return new Ip4Address(bytes);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070071 }
72
73 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080074 * Converts a byte array into an IPv4 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070075 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080076 * @param value the IPv4 address value stored in network byte order
77 * (i.e., the most significant byte first)
78 * @return an IPv4 address
79 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070080 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080081 public static Ip4Address valueOf(byte[] value) {
82 return new Ip4Address(value);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070083 }
84
85 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080086 * Converts a byte array and a given offset from the beginning of the
87 * array into an IPv4 address.
88 * <p>
89 * The IP address is stored in network byte order (i.e., the most
90 * significant byte first).
91 * </p>
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070092 * @param value the value to use
93 * @param offset the offset in bytes from the beginning of the byte array
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080094 * @return an IPv4 address
95 * @throws IllegalArgumentException if the arguments are invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -070096 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -080097 public static Ip4Address valueOf(byte[] value, int offset) {
98 IpAddress.checkArguments(VERSION, value, offset);
99 byte[] bc = Arrays.copyOfRange(value, offset, value.length);
100 return Ip4Address.valueOf(bc);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700101 }
102
103 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800104 * Converts an InetAddress into an IPv4 address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700105 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800106 * @param inetAddress the InetAddress value to use. It must contain an IPv4
107 * address
108 * @return an IPv4 address
109 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700110 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800111 public static Ip4Address valueOf(InetAddress inetAddress) {
112 byte[] bytes = inetAddress.getAddress();
113 if (inetAddress instanceof Inet4Address) {
114 return new Ip4Address(bytes);
115 }
116 if ((inetAddress instanceof Inet6Address) ||
117 (bytes.length == INET6_BYTE_LENGTH)) {
118 final String msg = "Invalid IPv4 version address string: " +
119 inetAddress.toString();
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700120 throw new IllegalArgumentException(msg);
121 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800122 // Use the number of bytes as a hint
123 if (bytes.length == INET_BYTE_LENGTH) {
124 return new Ip4Address(bytes);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700125 }
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800126 final String msg = "Unrecognized IP version address string: " +
127 inetAddress.toString();
128 throw new IllegalArgumentException(msg);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700129 }
130
131 /**
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800132 * Converts an IPv4 string literal (e.g., "10.2.3.4") into an IP address.
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700133 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800134 * @param value an IPv4 address value in string form
135 * @return an IPv4 address
136 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700137 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800138 public static Ip4Address valueOf(String value) {
139 InetAddress inetAddress = null;
140 try {
141 inetAddress = InetAddresses.forString(value);
142 } catch (IllegalArgumentException e) {
143 final String msg = "Invalid IP address string: " + value;
144 throw new IllegalArgumentException(msg);
145 }
146 return valueOf(inetAddress);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700147 }
148
149 /**
150 * Creates an IPv4 network mask prefix.
151 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800152 * @param prefixLength the length of the mask prefix. Must be in the
153 * interval [0, 32]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700154 * @return a new IPv4 address that contains a mask prefix of the
155 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800156 * @throws IllegalArgumentException if the argument is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700157 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800158 public static Ip4Address makeMaskPrefix(int prefixLength) {
159 byte[] mask = IpAddress.makeMaskPrefixArray(VERSION, prefixLength);
160 return new Ip4Address(mask);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700161 }
162
163 /**
164 * Creates an IPv4 address by masking it with a network mask of given
165 * mask length.
166 *
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800167 * @param address the address to mask
168 * @param prefixLength the length of the mask prefix. Must be in the
169 * interval [0, 32]
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700170 * @return a new IPv4 address that is masked with a mask prefix of the
171 * specified length
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800172 * @throws IllegalArgumentException if the prefix length is invalid
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700173 */
Pavlin Radoslavovf182f012014-11-04 15:03:18 -0800174 public static Ip4Address makeMaskedAddress(final Ip4Address address,
175 int prefixLength) {
176 byte[] net = makeMaskedAddressArray(address, prefixLength);
177 return Ip4Address.valueOf(net);
Pavlin Radoslavov9de27722014-10-23 20:31:15 -0700178 }
179}