blob: 7b7b9894d6df4ea99467ec1d771f88bf5a6f3172 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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.nio.ByteBuffer;
19import static com.google.common.base.Preconditions.checkNotNull;
20
21/**
22 * The class representing an IPv4 address.
23 * This class is immutable.
24 */
25public final class Ip4Address implements Comparable<Ip4Address> {
26 private final int value;
27
28 /** The length of the address in bytes (octets). */
29 public static final int BYTE_LENGTH = 4;
30
31 /** The length of the address in bits. */
32 public static final int BIT_LENGTH = BYTE_LENGTH * Byte.SIZE;
33
34 /**
35 * Default constructor.
36 */
37 public Ip4Address() {
38 this.value = 0;
39 }
40
41 /**
42 * Copy constructor.
43 *
44 * @param other the object to copy from
45 */
46 public Ip4Address(Ip4Address other) {
47 this.value = other.value;
48 }
49
50 /**
51 * Constructor from an integer value.
52 *
53 * @param value the value to use
54 */
55 public Ip4Address(int value) {
56 this.value = value;
57 }
58
59 /**
60 * Constructor from a byte array with the IPv4 address stored in network
61 * byte order (i.e., the most significant byte first).
62 *
63 * @param value the value to use
64 */
65 public Ip4Address(byte[] value) {
66 this(value, 0);
67 }
68
69 /**
70 * Constructor from a byte array with the IPv4 address stored in network
71 * byte order (i.e., the most significant byte first), and a given offset
72 * from the beginning of the byte array.
73 *
74 * @param value the value to use
75 * @param offset the offset in bytes from the beginning of the byte array
76 */
77 public Ip4Address(byte[] value, int offset) {
78 checkNotNull(value);
79
80 // Verify the arguments
81 if ((offset < 0) || (offset + BYTE_LENGTH > value.length)) {
82 String msg;
83 if (value.length < BYTE_LENGTH) {
84 msg = "Invalid IPv4 address array: array length: " +
85 value.length + ". Must be at least " + BYTE_LENGTH;
86 } else {
87 msg = "Invalid IPv4 address array: array offset: " +
88 offset + ". Must be in the interval [0, " +
89 (value.length - BYTE_LENGTH) + "]";
90 }
91 throw new IllegalArgumentException(msg);
92 }
93
94 // Read the address
95 ByteBuffer bb = ByteBuffer.wrap(value);
96 this.value = bb.getInt(offset);
97 }
98
99 /**
100 * Constructs an IPv4 address from a string representation of the address.
101 *<p>
102 * Example: "1.2.3.4"
103 *
104 * @param value the value to use
105 */
106 public Ip4Address(String value) {
107 checkNotNull(value);
108
109 String[] splits = value.split("\\.");
110 if (splits.length != 4) {
111 final String msg = "Invalid IPv4 address string: " + value;
112 throw new IllegalArgumentException(msg);
113 }
114
115 int result = 0;
116 for (int i = 0; i < BYTE_LENGTH; i++) {
117 result |= Integer.parseInt(splits[i]) <<
118 ((BYTE_LENGTH - (i + 1)) * Byte.SIZE);
119 }
120 this.value = result;
121 }
122
123 /**
124 * Gets the IPv4 address as a byte array.
125 *
126 * @return a byte array with the IPv4 address stored in network byte order
127 * (i.e., the most significant byte first).
128 */
129 public byte[] toOctets() {
130 return ByteBuffer.allocate(BYTE_LENGTH).putInt(value).array();
131 }
132
133 /**
134 * Creates an IPv4 network mask prefix.
135 *
136 * @param prefixLen the length of the mask prefix. Must be in the interval
137 * [0, 32].
138 * @return a new IPv4 address that contains a mask prefix of the
139 * specified length
140 */
141 public static Ip4Address makeMaskPrefix(int prefixLen) {
142 // Verify the prefix length
143 if ((prefixLen < 0) || (prefixLen > Ip4Address.BIT_LENGTH)) {
144 final String msg = "Invalid IPv4 prefix length: " + prefixLen +
145 ". Must be in the interval [0, 32].";
146 throw new IllegalArgumentException(msg);
147 }
148
149 long v =
150 (0xffffffffL << (Ip4Address.BIT_LENGTH - prefixLen)) & 0xffffffffL;
151 return new Ip4Address((int) v);
152 }
153
154 /**
155 * Creates an IPv4 address by masking it with a network mask of given
156 * mask length.
157 *
158 * @param addr the address to mask
159 * @param prefixLen the length of the mask prefix. Must be in the interval
160 * [0, 32].
161 * @return a new IPv4 address that is masked with a mask prefix of the
162 * specified length
163 */
164 public static Ip4Address makeMaskedAddress(final Ip4Address addr,
165 int prefixLen) {
166 Ip4Address mask = Ip4Address.makeMaskPrefix(prefixLen);
167 long v = addr.value & mask.value;
168
169 return new Ip4Address((int) v);
170 }
171
172 /**
173 * Gets the value of the IPv4 address.
174 *
175 * @return the value of the IPv4 address
176 */
177 public int getValue() {
178 return value;
179 }
180
181 /**
182 * Converts the IPv4 value to a '.' separated string.
183 *
184 * @return the IPv4 value as a '.' separated string
185 */
186 @Override
187 public String toString() {
188 return ((this.value >> 24) & 0xff) + "." +
189 ((this.value >> 16) & 0xff) + "." +
190 ((this.value >> 8) & 0xff) + "." +
191 (this.value & 0xff);
192 }
193
194 @Override
195 public boolean equals(Object o) {
196 if (!(o instanceof Ip4Address)) {
197 return false;
198 }
199 Ip4Address other = (Ip4Address) o;
200 if (this.value != other.value) {
201 return false;
202 }
203 return true;
204 }
205
206 @Override
207 public int hashCode() {
208 return this.value;
209 }
210
211 @Override
212 public int compareTo(Ip4Address o) {
213 Long lv = ((long) this.value) & 0xffffffffL;
214 Long rv = ((long) o.value) & 0xffffffffL;
215 return lv.compareTo(rv);
216 }
217}