Work toward common IP address classes.
Ported the following IP address classes from the older codebase: Ip4Address, Ip6Address, Ip4Prefix, Ip6Prefix (and the corresponding unit tests). NOTE: Those classes are not ready to be used yet. Change-Id: I234875abbc9df8daa2f8ae28706af591dd2c5f2d
Showing
8 changed files
with
1925 additions
and
0 deletions
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import java.nio.ByteBuffer; | ||
4 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
5 | + | ||
6 | +/** | ||
7 | + * The class representing an IPv4 address. | ||
8 | + * This class is immutable. | ||
9 | + */ | ||
10 | +public final class Ip4Address implements Comparable<Ip4Address> { | ||
11 | + private final int value; | ||
12 | + | ||
13 | + /** The length of the address in bytes (octets). */ | ||
14 | + public static final int BYTE_LENGTH = 4; | ||
15 | + | ||
16 | + /** The length of the address in bits. */ | ||
17 | + public static final int BIT_LENGTH = BYTE_LENGTH * Byte.SIZE; | ||
18 | + | ||
19 | + /** | ||
20 | + * Default constructor. | ||
21 | + */ | ||
22 | + public Ip4Address() { | ||
23 | + this.value = 0; | ||
24 | + } | ||
25 | + | ||
26 | + /** | ||
27 | + * Copy constructor. | ||
28 | + * | ||
29 | + * @param other the object to copy from | ||
30 | + */ | ||
31 | + public Ip4Address(Ip4Address other) { | ||
32 | + this.value = other.value; | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * Constructor from an integer value. | ||
37 | + * | ||
38 | + * @param value the value to use | ||
39 | + */ | ||
40 | + public Ip4Address(int value) { | ||
41 | + this.value = value; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Constructor from a byte array with the IPv4 address stored in network | ||
46 | + * byte order (i.e., the most significant byte first). | ||
47 | + * | ||
48 | + * @param value the value to use | ||
49 | + */ | ||
50 | + public Ip4Address(byte[] value) { | ||
51 | + this(value, 0); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * Constructor from a byte array with the IPv4 address stored in network | ||
56 | + * byte order (i.e., the most significant byte first), and a given offset | ||
57 | + * from the beginning of the byte array. | ||
58 | + * | ||
59 | + * @param value the value to use | ||
60 | + * @param offset the offset in bytes from the beginning of the byte array | ||
61 | + */ | ||
62 | + public Ip4Address(byte[] value, int offset) { | ||
63 | + checkNotNull(value); | ||
64 | + | ||
65 | + // Verify the arguments | ||
66 | + if ((offset < 0) || (offset + BYTE_LENGTH > value.length)) { | ||
67 | + String msg; | ||
68 | + if (value.length < BYTE_LENGTH) { | ||
69 | + msg = "Invalid IPv4 address array: array length: " + | ||
70 | + value.length + ". Must be at least " + BYTE_LENGTH; | ||
71 | + } else { | ||
72 | + msg = "Invalid IPv4 address array: array offset: " + | ||
73 | + offset + ". Must be in the interval [0, " + | ||
74 | + (value.length - BYTE_LENGTH) + "]"; | ||
75 | + } | ||
76 | + throw new IllegalArgumentException(msg); | ||
77 | + } | ||
78 | + | ||
79 | + // Read the address | ||
80 | + ByteBuffer bb = ByteBuffer.wrap(value); | ||
81 | + this.value = bb.getInt(offset); | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * Constructs an IPv4 address from a string representation of the address. | ||
86 | + *<p> | ||
87 | + * Example: "1.2.3.4" | ||
88 | + * | ||
89 | + * @param value the value to use | ||
90 | + */ | ||
91 | + public Ip4Address(String value) { | ||
92 | + checkNotNull(value); | ||
93 | + | ||
94 | + String[] splits = value.split("\\."); | ||
95 | + if (splits.length != 4) { | ||
96 | + final String msg = "Invalid IPv4 address string: " + value; | ||
97 | + throw new IllegalArgumentException(msg); | ||
98 | + } | ||
99 | + | ||
100 | + int result = 0; | ||
101 | + for (int i = 0; i < BYTE_LENGTH; i++) { | ||
102 | + result |= Integer.parseInt(splits[i]) << | ||
103 | + ((BYTE_LENGTH - (i + 1)) * Byte.SIZE); | ||
104 | + } | ||
105 | + this.value = result; | ||
106 | + } | ||
107 | + | ||
108 | + /** | ||
109 | + * Gets the IPv4 address as a byte array. | ||
110 | + * | ||
111 | + * @return a byte array with the IPv4 address stored in network byte order | ||
112 | + * (i.e., the most significant byte first). | ||
113 | + */ | ||
114 | + public byte[] toOctets() { | ||
115 | + return ByteBuffer.allocate(BYTE_LENGTH).putInt(value).array(); | ||
116 | + } | ||
117 | + | ||
118 | + /** | ||
119 | + * Creates an IPv4 network mask prefix. | ||
120 | + * | ||
121 | + * @param prefixLen the length of the mask prefix. Must be in the interval | ||
122 | + * [0, 32]. | ||
123 | + * @return a new IPv4 address that contains a mask prefix of the | ||
124 | + * specified length | ||
125 | + */ | ||
126 | + public static Ip4Address makeMaskPrefix(int prefixLen) { | ||
127 | + // Verify the prefix length | ||
128 | + if ((prefixLen < 0) || (prefixLen > Ip4Address.BIT_LENGTH)) { | ||
129 | + final String msg = "Invalid IPv4 prefix length: " + prefixLen + | ||
130 | + ". Must be in the interval [0, 32]."; | ||
131 | + throw new IllegalArgumentException(msg); | ||
132 | + } | ||
133 | + | ||
134 | + long v = | ||
135 | + (0xffffffffL << (Ip4Address.BIT_LENGTH - prefixLen)) & 0xffffffffL; | ||
136 | + return new Ip4Address((int) v); | ||
137 | + } | ||
138 | + | ||
139 | + /** | ||
140 | + * Creates an IPv4 address by masking it with a network mask of given | ||
141 | + * mask length. | ||
142 | + * | ||
143 | + * @param addr the address to mask | ||
144 | + * @param prefixLen the length of the mask prefix. Must be in the interval | ||
145 | + * [0, 32]. | ||
146 | + * @return a new IPv4 address that is masked with a mask prefix of the | ||
147 | + * specified length | ||
148 | + */ | ||
149 | + public static Ip4Address makeMaskedAddress(final Ip4Address addr, | ||
150 | + int prefixLen) { | ||
151 | + Ip4Address mask = Ip4Address.makeMaskPrefix(prefixLen); | ||
152 | + long v = addr.value & mask.value; | ||
153 | + | ||
154 | + return new Ip4Address((int) v); | ||
155 | + } | ||
156 | + | ||
157 | + /** | ||
158 | + * Gets the value of the IPv4 address. | ||
159 | + * | ||
160 | + * @return the value of the IPv4 address | ||
161 | + */ | ||
162 | + public int getValue() { | ||
163 | + return value; | ||
164 | + } | ||
165 | + | ||
166 | + /** | ||
167 | + * Converts the IPv4 value to a '.' separated string. | ||
168 | + * | ||
169 | + * @return the IPv4 value as a '.' separated string | ||
170 | + */ | ||
171 | + @Override | ||
172 | + public String toString() { | ||
173 | + return ((this.value >> 24) & 0xff) + "." + | ||
174 | + ((this.value >> 16) & 0xff) + "." + | ||
175 | + ((this.value >> 8) & 0xff) + "." + | ||
176 | + (this.value & 0xff); | ||
177 | + } | ||
178 | + | ||
179 | + @Override | ||
180 | + public boolean equals(Object o) { | ||
181 | + if (!(o instanceof Ip4Address)) { | ||
182 | + return false; | ||
183 | + } | ||
184 | + Ip4Address other = (Ip4Address) o; | ||
185 | + if (this.value != other.value) { | ||
186 | + return false; | ||
187 | + } | ||
188 | + return true; | ||
189 | + } | ||
190 | + | ||
191 | + @Override | ||
192 | + public int hashCode() { | ||
193 | + return this.value; | ||
194 | + } | ||
195 | + | ||
196 | + @Override | ||
197 | + public int compareTo(Ip4Address o) { | ||
198 | + Long lv = ((long) this.value) & 0xffffffffL; | ||
199 | + Long rv = ((long) o.value) & 0xffffffffL; | ||
200 | + return lv.compareTo(rv); | ||
201 | + } | ||
202 | +} |
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import java.util.Objects; | ||
4 | + | ||
5 | +/** | ||
6 | + * The class representing an IPv4 network address. | ||
7 | + * This class is immutable. | ||
8 | + */ | ||
9 | +public final class Ip4Prefix { | ||
10 | + private final Ip4Address address; // The IPv4 address | ||
11 | + private final short prefixLen; // The prefix length | ||
12 | + | ||
13 | + /** | ||
14 | + * Default constructor. | ||
15 | + */ | ||
16 | + public Ip4Prefix() { | ||
17 | + this.address = new Ip4Address(); | ||
18 | + this.prefixLen = 0; | ||
19 | + } | ||
20 | + | ||
21 | + /** | ||
22 | + * Copy constructor. | ||
23 | + * | ||
24 | + * @param other the object to copy from | ||
25 | + */ | ||
26 | + public Ip4Prefix(Ip4Prefix other) { | ||
27 | + this.address = new Ip4Address(other.address); | ||
28 | + this.prefixLen = other.prefixLen; | ||
29 | + } | ||
30 | + | ||
31 | + /** | ||
32 | + * Constructor for a given address and prefix length. | ||
33 | + * | ||
34 | + * @param address the address to use | ||
35 | + * @param prefixLen the prefix length to use | ||
36 | + */ | ||
37 | + public Ip4Prefix(Ip4Address address, short prefixLen) { | ||
38 | + this.address = Ip4Address.makeMaskedAddress(address, prefixLen); | ||
39 | + this.prefixLen = prefixLen; | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * Constructs an IPv4 prefix from a string representation of the | ||
44 | + * prefix. | ||
45 | + *<p> | ||
46 | + * Example: "1.2.0.0/16" | ||
47 | + * | ||
48 | + * @param value the value to use | ||
49 | + */ | ||
50 | + public Ip4Prefix(String value) { | ||
51 | + String[] splits = value.split("/"); | ||
52 | + if (splits.length != 2) { | ||
53 | + throw new IllegalArgumentException("Specified IPv4 prefix must contain an IPv4 " + | ||
54 | + "address and a prefix length separated by '/'"); | ||
55 | + } | ||
56 | + this.prefixLen = Short.decode(splits[1]); | ||
57 | + this.address = Ip4Address.makeMaskedAddress(new Ip4Address(splits[0]), | ||
58 | + this.prefixLen); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Gets the address value of the IPv4 prefix. | ||
63 | + * | ||
64 | + * @return the address value of the IPv4 prefix | ||
65 | + */ | ||
66 | + public Ip4Address getAddress() { | ||
67 | + return address; | ||
68 | + } | ||
69 | + | ||
70 | + /** | ||
71 | + * Gets the prefix length value of the IPv4 prefix. | ||
72 | + * | ||
73 | + * @return the prefix length value of the IPv4 prefix | ||
74 | + */ | ||
75 | + public short getPrefixLen() { | ||
76 | + return prefixLen; | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
80 | + * Converts the IPv4 prefix value to an "address/prefixLen" string. | ||
81 | + * | ||
82 | + * @return the IPv4 prefix value as an "address/prefixLen" string | ||
83 | + */ | ||
84 | + @Override | ||
85 | + public String toString() { | ||
86 | + return this.address.toString() + "/" + this.prefixLen; | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * Compares the value of two Ip4Prefix objects. | ||
91 | + * <p/> | ||
92 | + * Note the value of the IPv4 address is compared directly between the | ||
93 | + * objects, and must match exactly for the objects to be considered equal. | ||
94 | + * This may result in objects which represent the same IP prefix being | ||
95 | + * classified as unequal, because the unsignificant bits of the address | ||
96 | + * field don't match (the bits to the right of the prefix length). | ||
97 | + * <p/> | ||
98 | + * TODO Change this behavior so that objects that represent the same prefix | ||
99 | + * are classified as equal according to this equals method. | ||
100 | + * | ||
101 | + * @see Object#equals(Object) | ||
102 | + */ | ||
103 | + @Override | ||
104 | + public boolean equals(Object other) { | ||
105 | + if (other == this) { | ||
106 | + return true; | ||
107 | + } | ||
108 | + | ||
109 | + if (!(other instanceof Ip4Prefix)) { | ||
110 | + return false; | ||
111 | + } | ||
112 | + | ||
113 | + Ip4Prefix otherIp4Prefix = (Ip4Prefix) other; | ||
114 | + | ||
115 | + return Objects.equals(this.address, otherIp4Prefix.address) | ||
116 | + && this.prefixLen == otherIp4Prefix.prefixLen; | ||
117 | + } | ||
118 | + | ||
119 | + @Override | ||
120 | + public int hashCode() { | ||
121 | + return Objects.hash(address, prefixLen); | ||
122 | + } | ||
123 | +} |
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import java.net.InetAddress; | ||
4 | +import java.net.UnknownHostException; | ||
5 | +import java.nio.ByteBuffer; | ||
6 | +import java.util.Objects; | ||
7 | + | ||
8 | +import com.google.common.net.InetAddresses; | ||
9 | +import com.google.common.primitives.UnsignedLongs; | ||
10 | + | ||
11 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
12 | +import static com.google.common.base.Preconditions.checkState; | ||
13 | + | ||
14 | +/** | ||
15 | + * The class representing an IPv6 address. | ||
16 | + * This class is immutable. | ||
17 | + */ | ||
18 | +public final class Ip6Address implements Comparable<Ip6Address> { | ||
19 | + private final long valueHigh; // The higher (more significant) 64 bits | ||
20 | + private final long valueLow; // The lower (less significant) 64 bits | ||
21 | + | ||
22 | + /** The length of the address in bytes (octets). */ | ||
23 | + public static final int BYTE_LENGTH = 16; | ||
24 | + | ||
25 | + /** The length of the address in bits. */ | ||
26 | + public static final int BIT_LENGTH = BYTE_LENGTH * Byte.SIZE; | ||
27 | + | ||
28 | + /** | ||
29 | + * Default constructor. | ||
30 | + */ | ||
31 | + public Ip6Address() { | ||
32 | + this.valueHigh = 0; | ||
33 | + this.valueLow = 0; | ||
34 | + } | ||
35 | + | ||
36 | + /** | ||
37 | + * Copy constructor. | ||
38 | + * | ||
39 | + * @param other the object to copy from | ||
40 | + */ | ||
41 | + public Ip6Address(Ip6Address other) { | ||
42 | + this.valueHigh = other.valueHigh; | ||
43 | + this.valueLow = other.valueLow; | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Constructor from integer values. | ||
48 | + * | ||
49 | + * @param valueHigh the higher (more significant) 64 bits of the address | ||
50 | + * @param valueLow the lower (less significant) 64 bits of the address | ||
51 | + */ | ||
52 | + public Ip6Address(long valueHigh, long valueLow) { | ||
53 | + this.valueHigh = valueHigh; | ||
54 | + this.valueLow = valueLow; | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * Constructor from a byte array with the IPv6 address stored in network | ||
59 | + * byte order (i.e., the most significant byte first). | ||
60 | + * | ||
61 | + * @param value the value to use | ||
62 | + */ | ||
63 | + public Ip6Address(byte[] value) { | ||
64 | + this(value, 0); | ||
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * Constructor from a byte array with the IPv6 address stored in network | ||
69 | + * byte order (i.e., the most significant byte first), and a given offset | ||
70 | + * from the beginning of the byte array. | ||
71 | + * | ||
72 | + * @param value the value to use | ||
73 | + * @param offset the offset in bytes from the beginning of the byte array | ||
74 | + */ | ||
75 | + public Ip6Address(byte[] value, int offset) { | ||
76 | + checkNotNull(value); | ||
77 | + | ||
78 | + // Verify the arguments | ||
79 | + if ((offset < 0) || (offset + BYTE_LENGTH > value.length)) { | ||
80 | + String msg; | ||
81 | + if (value.length < BYTE_LENGTH) { | ||
82 | + msg = "Invalid IPv6 address array: array length: " + | ||
83 | + value.length + ". Must be at least " + BYTE_LENGTH; | ||
84 | + } else { | ||
85 | + msg = "Invalid IPv6 address array: array offset: " + | ||
86 | + offset + ". Must be in the interval [0, " + | ||
87 | + (value.length - BYTE_LENGTH) + "]"; | ||
88 | + } | ||
89 | + throw new IllegalArgumentException(msg); | ||
90 | + } | ||
91 | + | ||
92 | + // Read the address | ||
93 | + ByteBuffer bb = ByteBuffer.wrap(value); | ||
94 | + bb.position(offset); | ||
95 | + this.valueHigh = bb.getLong(); | ||
96 | + this.valueLow = bb.getLong(); | ||
97 | + } | ||
98 | + | ||
99 | + /** | ||
100 | + * Constructs an IPv6 address from a string representation of the address. | ||
101 | + *<p> | ||
102 | + * Example: "1111:2222::8888" | ||
103 | + * | ||
104 | + * @param value the value to use | ||
105 | + */ | ||
106 | + public Ip6Address(String value) { | ||
107 | + checkNotNull(value); | ||
108 | + | ||
109 | + if (value.isEmpty()) { | ||
110 | + final String msg = "Specified IPv6 cannot be an empty string"; | ||
111 | + throw new IllegalArgumentException(msg); | ||
112 | + } | ||
113 | + InetAddress addr = null; | ||
114 | + try { | ||
115 | + addr = InetAddresses.forString(value); | ||
116 | + } catch (IllegalArgumentException e) { | ||
117 | + final String msg = "Invalid IPv6 address string: " + value; | ||
118 | + throw new IllegalArgumentException(msg); | ||
119 | + } | ||
120 | + byte[] bytes = addr.getAddress(); | ||
121 | + ByteBuffer bb = ByteBuffer.wrap(bytes); | ||
122 | + this.valueHigh = bb.getLong(); | ||
123 | + this.valueLow = bb.getLong(); | ||
124 | + } | ||
125 | + | ||
126 | + /** | ||
127 | + * Gets the IPv6 address as a byte array. | ||
128 | + * | ||
129 | + * @return a byte array with the IPv6 address stored in network byte order | ||
130 | + * (i.e., the most significant byte first). | ||
131 | + */ | ||
132 | + public byte[] toOctets() { | ||
133 | + return ByteBuffer.allocate(BYTE_LENGTH) | ||
134 | + .putLong(valueHigh).putLong(valueLow).array(); | ||
135 | + } | ||
136 | + | ||
137 | + /** | ||
138 | + * Creates an IPv6 network mask prefix. | ||
139 | + * | ||
140 | + * @param prefixLen the length of the mask prefix. Must be in the interval | ||
141 | + * [0, 128]. | ||
142 | + * @return a new IPv6 address that contains a mask prefix of the | ||
143 | + * specified length | ||
144 | + */ | ||
145 | + public static Ip6Address makeMaskPrefix(int prefixLen) { | ||
146 | + long vh, vl; | ||
147 | + | ||
148 | + // Verify the prefix length | ||
149 | + if ((prefixLen < 0) || (prefixLen > Ip6Address.BIT_LENGTH)) { | ||
150 | + final String msg = "Invalid IPv6 prefix length: " + prefixLen + | ||
151 | + ". Must be in the interval [0, 128]."; | ||
152 | + throw new IllegalArgumentException(msg); | ||
153 | + } | ||
154 | + | ||
155 | + if (prefixLen == 0) { | ||
156 | + // | ||
157 | + // NOTE: Apparently, the result of "<< 64" shifting to the left | ||
158 | + // results in all 1s instead of all 0s, hence we handle it as | ||
159 | + // a special case. | ||
160 | + // | ||
161 | + vh = 0; | ||
162 | + vl = 0; | ||
163 | + } else if (prefixLen <= 64) { | ||
164 | + vh = (0xffffffffffffffffL << (64 - prefixLen)) & 0xffffffffffffffffL; | ||
165 | + vl = 0; | ||
166 | + } else { | ||
167 | + vh = -1L; // All 1s | ||
168 | + vl = (0xffffffffffffffffL << (128 - prefixLen)) & 0xffffffffffffffffL; | ||
169 | + } | ||
170 | + return new Ip6Address(vh, vl); | ||
171 | + } | ||
172 | + | ||
173 | + /** | ||
174 | + * Creates an IPv6 address by masking it with a network mask of given | ||
175 | + * mask length. | ||
176 | + * | ||
177 | + * @param addr the address to mask | ||
178 | + * @param prefixLen the length of the mask prefix. Must be in the interval | ||
179 | + * [0, 128]. | ||
180 | + * @return a new IPv6 address that is masked with a mask prefix of the | ||
181 | + * specified length | ||
182 | + */ | ||
183 | + public static Ip6Address makeMaskedAddress(final Ip6Address addr, | ||
184 | + int prefixLen) { | ||
185 | + Ip6Address mask = Ip6Address.makeMaskPrefix(prefixLen); | ||
186 | + long vh = addr.valueHigh & mask.valueHigh; | ||
187 | + long vl = addr.valueLow & mask.valueLow; | ||
188 | + | ||
189 | + return new Ip6Address(vh, vl); | ||
190 | + } | ||
191 | + | ||
192 | + /** | ||
193 | + * Gets the value of the higher (more significant) 64 bits of the address. | ||
194 | + * | ||
195 | + * @return the value of the higher (more significant) 64 bits of the | ||
196 | + * address | ||
197 | + */ | ||
198 | + public long getValueHigh() { | ||
199 | + return valueHigh; | ||
200 | + } | ||
201 | + | ||
202 | + /** | ||
203 | + * Gets the value of the lower (less significant) 64 bits of the address. | ||
204 | + * | ||
205 | + * @return the value of the lower (less significant) 64 bits of the | ||
206 | + * address | ||
207 | + */ | ||
208 | + public long getValueLow() { | ||
209 | + return valueLow; | ||
210 | + } | ||
211 | + | ||
212 | + /** | ||
213 | + * Converts the IPv6 value to a ':' separated string. | ||
214 | + * | ||
215 | + * @return the IPv6 value as a ':' separated string | ||
216 | + */ | ||
217 | + @Override | ||
218 | + public String toString() { | ||
219 | + ByteBuffer bb = ByteBuffer.allocate(Ip6Address.BYTE_LENGTH); | ||
220 | + bb.putLong(valueHigh); | ||
221 | + bb.putLong(valueLow); | ||
222 | + InetAddress inetAddr = null; | ||
223 | + try { | ||
224 | + inetAddr = InetAddress.getByAddress(bb.array()); | ||
225 | + } catch (UnknownHostException e) { | ||
226 | + // Should never happen | ||
227 | + checkState(false, "Internal error: Ip6Address.toString()"); | ||
228 | + return "::"; | ||
229 | + } | ||
230 | + return InetAddresses.toAddrString(inetAddr); | ||
231 | + } | ||
232 | + | ||
233 | + @Override | ||
234 | + public boolean equals(Object o) { | ||
235 | + if (!(o instanceof Ip6Address)) { | ||
236 | + return false; | ||
237 | + } | ||
238 | + Ip6Address other = (Ip6Address) o; | ||
239 | + return this.valueHigh == other.valueHigh | ||
240 | + && this.valueLow == other.valueLow; | ||
241 | + } | ||
242 | + | ||
243 | + @Override | ||
244 | + public int hashCode() { | ||
245 | + return Objects.hash(valueHigh, valueLow); | ||
246 | + } | ||
247 | + | ||
248 | + @Override | ||
249 | + public int compareTo(Ip6Address o) { | ||
250 | + // Compare the high-order 64-bit value | ||
251 | + if (this.valueHigh != o.valueHigh) { | ||
252 | + return UnsignedLongs.compare(this.valueHigh, o.valueHigh); | ||
253 | + } | ||
254 | + // Compare the low-order 64-bit value | ||
255 | + if (this.valueLow != o.valueLow) { | ||
256 | + return UnsignedLongs.compare(this.valueLow, o.valueLow); | ||
257 | + } | ||
258 | + return 0; | ||
259 | + } | ||
260 | +} |
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import java.util.Objects; | ||
4 | + | ||
5 | +/** | ||
6 | + * The class representing an IPv6 network address. | ||
7 | + * This class is immutable. | ||
8 | + */ | ||
9 | +public final class Ip6Prefix { | ||
10 | + private final Ip6Address address; // The IPv6 address | ||
11 | + private final short prefixLen; // The prefix length | ||
12 | + | ||
13 | + /** | ||
14 | + * Default constructor. | ||
15 | + */ | ||
16 | + public Ip6Prefix() { | ||
17 | + this.address = new Ip6Address(); | ||
18 | + this.prefixLen = 0; | ||
19 | + } | ||
20 | + | ||
21 | + /** | ||
22 | + * Copy constructor. | ||
23 | + * | ||
24 | + * @param other the object to copy from | ||
25 | + */ | ||
26 | + public Ip6Prefix(Ip6Prefix other) { | ||
27 | + this.address = new Ip6Address(other.address); | ||
28 | + this.prefixLen = other.prefixLen; | ||
29 | + } | ||
30 | + | ||
31 | + /** | ||
32 | + * Constructor for a given address and prefix length. | ||
33 | + * | ||
34 | + * @param address the address to use | ||
35 | + * @param prefixLen the prefix length to use | ||
36 | + */ | ||
37 | + public Ip6Prefix(Ip6Address address, short prefixLen) { | ||
38 | + this.address = Ip6Address.makeMaskedAddress(address, prefixLen); | ||
39 | + this.prefixLen = prefixLen; | ||
40 | + } | ||
41 | + | ||
42 | + /** | ||
43 | + * Constructs an IPv6 prefix from a string representation of the | ||
44 | + * prefix. | ||
45 | + *<p> | ||
46 | + * Example: "1111:2222::/32" | ||
47 | + * | ||
48 | + * @param value the value to use | ||
49 | + */ | ||
50 | + public Ip6Prefix(String value) { | ||
51 | + String[] splits = value.split("/"); | ||
52 | + if (splits.length != 2) { | ||
53 | + throw new IllegalArgumentException("Specified IPv6 prefix must contain an IPv6 " + | ||
54 | + "address and a prefix length separated by '/'"); | ||
55 | + } | ||
56 | + this.prefixLen = Short.decode(splits[1]); | ||
57 | + this.address = Ip6Address.makeMaskedAddress(new Ip6Address(splits[0]), | ||
58 | + this.prefixLen); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Gets the address value of the IPv6 prefix. | ||
63 | + * | ||
64 | + * @return the address value of the IPv6 prefix | ||
65 | + */ | ||
66 | + public Ip6Address getAddress() { | ||
67 | + return address; | ||
68 | + } | ||
69 | + | ||
70 | + /** | ||
71 | + * Gets the prefix length value of the IPv6 prefix. | ||
72 | + * | ||
73 | + * @return the prefix length value of the IPv6 prefix | ||
74 | + */ | ||
75 | + public short getPrefixLen() { | ||
76 | + return prefixLen; | ||
77 | + } | ||
78 | + | ||
79 | + /** | ||
80 | + * Converts the IPv6 prefix value to an "address/prefixLen" string. | ||
81 | + * | ||
82 | + * @return the IPv6 prefix value as an "address/prefixLen" string | ||
83 | + */ | ||
84 | + @Override | ||
85 | + public String toString() { | ||
86 | + return this.address.toString() + "/" + this.prefixLen; | ||
87 | + } | ||
88 | + | ||
89 | + /** | ||
90 | + * Compares the value of two Ip6Prefix objects. | ||
91 | + * <p/> | ||
92 | + * Note the value of the IPv6 address is compared directly between the | ||
93 | + * objects, and must match exactly for the objects to be considered equal. | ||
94 | + * This may result in objects which represent the same IP prefix being | ||
95 | + * classified as unequal, because the unsignificant bits of the address | ||
96 | + * field don't match (the bits to the right of the prefix length). | ||
97 | + * <p/> | ||
98 | + * TODO Change this behavior so that objects that represent the same prefix | ||
99 | + * are classified as equal according to this equals method. | ||
100 | + * | ||
101 | + * @see Object#equals(Object) | ||
102 | + */ | ||
103 | + @Override | ||
104 | + public boolean equals(Object other) { | ||
105 | + if (other == this) { | ||
106 | + return true; | ||
107 | + } | ||
108 | + | ||
109 | + if (!(other instanceof Ip6Prefix)) { | ||
110 | + return false; | ||
111 | + } | ||
112 | + | ||
113 | + Ip6Prefix otherIp6Prefix = (Ip6Prefix) other; | ||
114 | + | ||
115 | + return Objects.equals(this.address, otherIp6Prefix.address) | ||
116 | + && this.prefixLen == otherIp6Prefix.prefixLen; | ||
117 | + } | ||
118 | + | ||
119 | + @Override | ||
120 | + public int hashCode() { | ||
121 | + return Objects.hash(address, prefixLen); | ||
122 | + } | ||
123 | +} |
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import org.junit.Test; | ||
4 | + | ||
5 | +import static org.hamcrest.Matchers.is; | ||
6 | +import static org.hamcrest.Matchers.not; | ||
7 | +import static org.junit.Assert.assertThat; | ||
8 | +import static org.junit.Assert.assertTrue; | ||
9 | +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; | ||
10 | + | ||
11 | +/** | ||
12 | + * Tests for class {@link Ip4Address}. | ||
13 | + */ | ||
14 | +public class Ip4AddressTest { | ||
15 | + /** | ||
16 | + * Tests the immutability of {@link Ip4Address}. | ||
17 | + */ | ||
18 | + @Test | ||
19 | + public void testImmutable() { | ||
20 | + assertThatClassIsImmutable(Ip4Address.class); | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * Tests the length of the address in bytes (octets). | ||
25 | + */ | ||
26 | + @Test | ||
27 | + public void testAddrBytelen() { | ||
28 | + assertThat(Ip4Address.BYTE_LENGTH, is(4)); | ||
29 | + } | ||
30 | + | ||
31 | + /** | ||
32 | + * Tests the length of the address in bits. | ||
33 | + */ | ||
34 | + @Test | ||
35 | + public void testAddrBitlen() { | ||
36 | + assertThat(Ip4Address.BIT_LENGTH, is(32)); | ||
37 | + } | ||
38 | + | ||
39 | + /** | ||
40 | + * Tests default class constructor. | ||
41 | + */ | ||
42 | + @Test | ||
43 | + public void testDefaultConstructor() { | ||
44 | + Ip4Address ip4Address = new Ip4Address(); | ||
45 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Tests valid class copy constructor. | ||
50 | + */ | ||
51 | + @Test | ||
52 | + public void testCopyConstructor() { | ||
53 | + Ip4Address fromAddr = new Ip4Address("1.2.3.4"); | ||
54 | + Ip4Address ip4Address = new Ip4Address(fromAddr); | ||
55 | + assertThat(ip4Address.toString(), is("1.2.3.4")); | ||
56 | + | ||
57 | + fromAddr = new Ip4Address("0.0.0.0"); | ||
58 | + ip4Address = new Ip4Address(fromAddr); | ||
59 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
60 | + | ||
61 | + fromAddr = new Ip4Address("255.255.255.255"); | ||
62 | + ip4Address = new Ip4Address(fromAddr); | ||
63 | + assertThat(ip4Address.toString(), is("255.255.255.255")); | ||
64 | + } | ||
65 | + | ||
66 | + /** | ||
67 | + * Tests invalid class copy constructor for a null object to copy from. | ||
68 | + */ | ||
69 | + @Test(expected = NullPointerException.class) | ||
70 | + public void testInvalidConstructorNullObject() { | ||
71 | + Ip4Address fromAddr = null; | ||
72 | + Ip4Address ip4Address = new Ip4Address(fromAddr); | ||
73 | + } | ||
74 | + | ||
75 | + /** | ||
76 | + * Tests valid class constructor for an integer value. | ||
77 | + */ | ||
78 | + @Test | ||
79 | + public void testConstructorForInteger() { | ||
80 | + Ip4Address ip4Address = new Ip4Address(0x01020304); | ||
81 | + assertThat(ip4Address.toString(), is("1.2.3.4")); | ||
82 | + | ||
83 | + ip4Address = new Ip4Address(0); | ||
84 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
85 | + | ||
86 | + ip4Address = new Ip4Address(0xffffffff); | ||
87 | + assertThat(ip4Address.toString(), is("255.255.255.255")); | ||
88 | + } | ||
89 | + | ||
90 | + /** | ||
91 | + * Tests valid class constructor for an array value. | ||
92 | + */ | ||
93 | + @Test | ||
94 | + public void testConstructorForArray() { | ||
95 | + final byte[] value1 = new byte[] {1, 2, 3, 4}; | ||
96 | + Ip4Address ip4Address = new Ip4Address(value1); | ||
97 | + assertThat(ip4Address.toString(), is("1.2.3.4")); | ||
98 | + | ||
99 | + final byte[] value2 = new byte[] {0, 0, 0, 0}; | ||
100 | + ip4Address = new Ip4Address(value2); | ||
101 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
102 | + | ||
103 | + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff, | ||
104 | + (byte) 0xff, (byte) 0xff}; | ||
105 | + ip4Address = new Ip4Address(value3); | ||
106 | + assertThat(ip4Address.toString(), is("255.255.255.255")); | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
110 | + * Tests valid class constructor for an array value and an offset. | ||
111 | + */ | ||
112 | + @Test | ||
113 | + public void testConstructorForArrayAndOffset() { | ||
114 | + final byte[] value1 = new byte[] {11, 22, 33, // Preamble | ||
115 | + 1, 2, 3, 4, | ||
116 | + 44, 55}; // Extra bytes | ||
117 | + Ip4Address ip4Address = new Ip4Address(value1, 3); | ||
118 | + assertThat(ip4Address.toString(), is("1.2.3.4")); | ||
119 | + | ||
120 | + final byte[] value2 = new byte[] {11, 22, // Preamble | ||
121 | + 0, 0, 0, 0, | ||
122 | + 33}; // Extra bytes | ||
123 | + ip4Address = new Ip4Address(value2, 2); | ||
124 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
125 | + | ||
126 | + final byte[] value3 = new byte[] {11, 22, // Preamble | ||
127 | + (byte) 0xff, (byte) 0xff, | ||
128 | + (byte) 0xff, (byte) 0xff, | ||
129 | + 33}; // Extra bytes | ||
130 | + ip4Address = new Ip4Address(value3, 2); | ||
131 | + assertThat(ip4Address.toString(), is("255.255.255.255")); | ||
132 | + } | ||
133 | + | ||
134 | + /** | ||
135 | + * Tests invalid class constructor for a null array. | ||
136 | + */ | ||
137 | + @Test(expected = NullPointerException.class) | ||
138 | + public void testInvalidConstructorNullArray() { | ||
139 | + final byte[] fromArray = null; | ||
140 | + Ip4Address ip4Address = new Ip4Address(fromArray); | ||
141 | + } | ||
142 | + | ||
143 | + /** | ||
144 | + * Tests invalid class constructor for an array that is too short. | ||
145 | + */ | ||
146 | + @Test(expected = IllegalArgumentException.class) | ||
147 | + public void testInvalidConstructorShortArray() { | ||
148 | + final byte[] fromArray = new byte[] {1, 2, 3}; | ||
149 | + Ip4Address ip4Address = new Ip4Address(fromArray); | ||
150 | + } | ||
151 | + | ||
152 | + /** | ||
153 | + * Tests invalid class constructor for an array and an invalid offset. | ||
154 | + */ | ||
155 | + @Test(expected = IllegalArgumentException.class) | ||
156 | + public void testInvalidConstructorArrayInvalidOffset() { | ||
157 | + final byte[] value1 = new byte[] {11, 22, 33, // Preamble | ||
158 | + 1, 2, 3, 4, | ||
159 | + 44, 55}; // Extra bytes | ||
160 | + Ip4Address ip4Address = new Ip4Address(value1, 6); | ||
161 | + } | ||
162 | + | ||
163 | + /** | ||
164 | + * Tests valid class constructor for a string. | ||
165 | + */ | ||
166 | + @Test | ||
167 | + public void testConstructorForString() { | ||
168 | + Ip4Address ip4Address = new Ip4Address("1.2.3.4"); | ||
169 | + assertThat(ip4Address.toString(), is("1.2.3.4")); | ||
170 | + | ||
171 | + ip4Address = new Ip4Address("0.0.0.0"); | ||
172 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
173 | + | ||
174 | + ip4Address = new Ip4Address("255.255.255.255"); | ||
175 | + assertThat(ip4Address.toString(), is("255.255.255.255")); | ||
176 | + } | ||
177 | + | ||
178 | + /** | ||
179 | + * Tests invalid class constructor for a null string. | ||
180 | + */ | ||
181 | + @Test(expected = NullPointerException.class) | ||
182 | + public void testInvalidConstructorNullString() { | ||
183 | + String fromString = null; | ||
184 | + Ip4Address ip4Address = new Ip4Address(fromString); | ||
185 | + } | ||
186 | + | ||
187 | + /** | ||
188 | + * Tests invalid class constructor for an empty string. | ||
189 | + */ | ||
190 | + @Test(expected = IllegalArgumentException.class) | ||
191 | + public void testInvalidConstructors() { | ||
192 | + // Check constructor for invalid ID: empty string | ||
193 | + Ip4Address ip4Address = new Ip4Address(""); | ||
194 | + } | ||
195 | + | ||
196 | + /** | ||
197 | + * Tests returning the address as a byte array. | ||
198 | + */ | ||
199 | + @Test | ||
200 | + public void testAddressToOctets() { | ||
201 | + final byte[] value1 = new byte[] {1, 2, 3, 4}; | ||
202 | + Ip4Address ip4Address = new Ip4Address("1.2.3.4"); | ||
203 | + assertThat(ip4Address.toOctets(), is(value1)); | ||
204 | + | ||
205 | + final byte[] value2 = new byte[] {0, 0, 0, 0}; | ||
206 | + ip4Address = new Ip4Address("0.0.0.0"); | ||
207 | + assertThat(ip4Address.toOctets(), is(value2)); | ||
208 | + | ||
209 | + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff, | ||
210 | + (byte) 0xff, (byte) 0xff}; | ||
211 | + ip4Address = new Ip4Address("255.255.255.255"); | ||
212 | + assertThat(ip4Address.toOctets(), is(value3)); | ||
213 | + } | ||
214 | + | ||
215 | + /** | ||
216 | + * Tests making a mask prefix for a given prefix length. | ||
217 | + */ | ||
218 | + @Test | ||
219 | + public void testMakeMaskPrefix() { | ||
220 | + Ip4Address ip4Address = Ip4Address.makeMaskPrefix(25); | ||
221 | + assertThat(ip4Address.toString(), is("255.255.255.128")); | ||
222 | + | ||
223 | + ip4Address = Ip4Address.makeMaskPrefix(0); | ||
224 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
225 | + | ||
226 | + ip4Address = Ip4Address.makeMaskPrefix(32); | ||
227 | + assertThat(ip4Address.toString(), is("255.255.255.255")); | ||
228 | + } | ||
229 | + | ||
230 | + /** | ||
231 | + * Tests making of a masked address. | ||
232 | + */ | ||
233 | + @Test | ||
234 | + public void testMakeMaskedAddress() { | ||
235 | + Ip4Address ip4Address = new Ip4Address("1.2.3.5"); | ||
236 | + Ip4Address ip4AddressMasked = | ||
237 | + Ip4Address.makeMaskedAddress(ip4Address, 24); | ||
238 | + assertThat(ip4AddressMasked.toString(), is("1.2.3.0")); | ||
239 | + | ||
240 | + ip4AddressMasked = Ip4Address.makeMaskedAddress(ip4Address, 0); | ||
241 | + assertThat(ip4AddressMasked.toString(), is("0.0.0.0")); | ||
242 | + | ||
243 | + ip4AddressMasked = Ip4Address.makeMaskedAddress(ip4Address, 32); | ||
244 | + assertThat(ip4AddressMasked.toString(), is("1.2.3.5")); | ||
245 | + } | ||
246 | + | ||
247 | + /** | ||
248 | + * Tests getting the value of an address. | ||
249 | + */ | ||
250 | + @Test | ||
251 | + public void testGetValue() { | ||
252 | + Ip4Address ip4Address = new Ip4Address("1.2.3.4"); | ||
253 | + assertThat(ip4Address.getValue(), is(0x01020304)); | ||
254 | + | ||
255 | + ip4Address = new Ip4Address("0.0.0.0"); | ||
256 | + assertThat(ip4Address.getValue(), is(0)); | ||
257 | + | ||
258 | + ip4Address = new Ip4Address("255.255.255.255"); | ||
259 | + assertThat(ip4Address.getValue(), is(-1)); | ||
260 | + } | ||
261 | + | ||
262 | + /** | ||
263 | + * Tests equality of {@link Ip4Address}. | ||
264 | + */ | ||
265 | + @Test | ||
266 | + public void testEquality() { | ||
267 | + Ip4Address addr1 = new Ip4Address("1.2.3.4"); | ||
268 | + Ip4Address addr2 = new Ip4Address("1.2.3.4"); | ||
269 | + assertThat(addr1, is(addr2)); | ||
270 | + | ||
271 | + addr1 = new Ip4Address("0.0.0.0"); | ||
272 | + addr2 = new Ip4Address("0.0.0.0"); | ||
273 | + assertThat(addr1, is(addr2)); | ||
274 | + | ||
275 | + addr1 = new Ip4Address("255.255.255.255"); | ||
276 | + addr2 = new Ip4Address("255.255.255.255"); | ||
277 | + assertThat(addr1, is(addr2)); | ||
278 | + } | ||
279 | + | ||
280 | + /** | ||
281 | + * Tests non-equality of {@link Ip4Address}. | ||
282 | + */ | ||
283 | + @Test | ||
284 | + public void testNonEquality() { | ||
285 | + Ip4Address addr1 = new Ip4Address("1.2.3.4"); | ||
286 | + Ip4Address addr2 = new Ip4Address("1.2.3.5"); | ||
287 | + Ip4Address addr3 = new Ip4Address("0.0.0.0"); | ||
288 | + Ip4Address addr4 = new Ip4Address("255.255.255.255"); | ||
289 | + assertThat(addr1, is(not(addr2))); | ||
290 | + assertThat(addr3, is(not(addr2))); | ||
291 | + assertThat(addr4, is(not(addr2))); | ||
292 | + } | ||
293 | + | ||
294 | + /** | ||
295 | + * Tests comparison of {@link Ip4Address}. | ||
296 | + */ | ||
297 | + @Test | ||
298 | + public void testComparison() { | ||
299 | + Ip4Address addr1 = new Ip4Address("1.2.3.4"); | ||
300 | + Ip4Address addr2 = new Ip4Address("1.2.3.4"); | ||
301 | + Ip4Address addr3 = new Ip4Address("1.2.3.3"); | ||
302 | + Ip4Address addr4 = new Ip4Address("1.2.3.5"); | ||
303 | + assertTrue(addr1.compareTo(addr2) == 0); | ||
304 | + assertTrue(addr1.compareTo(addr3) > 0); | ||
305 | + assertTrue(addr1.compareTo(addr4) < 0); | ||
306 | + | ||
307 | + addr1 = new Ip4Address("255.2.3.4"); | ||
308 | + addr2 = new Ip4Address("255.2.3.4"); | ||
309 | + addr3 = new Ip4Address("255.2.3.3"); | ||
310 | + addr4 = new Ip4Address("255.2.3.5"); | ||
311 | + assertTrue(addr1.compareTo(addr2) == 0); | ||
312 | + assertTrue(addr1.compareTo(addr3) > 0); | ||
313 | + assertTrue(addr1.compareTo(addr4) < 0); | ||
314 | + } | ||
315 | + | ||
316 | + /** | ||
317 | + * Tests object string representation. | ||
318 | + */ | ||
319 | + @Test | ||
320 | + public void testToString() { | ||
321 | + Ip4Address ip4Address = new Ip4Address("1.2.3.4"); | ||
322 | + assertThat(ip4Address.toString(), is("1.2.3.4")); | ||
323 | + | ||
324 | + ip4Address = new Ip4Address("0.0.0.0"); | ||
325 | + assertThat(ip4Address.toString(), is("0.0.0.0")); | ||
326 | + | ||
327 | + ip4Address = new Ip4Address("255.255.255.255"); | ||
328 | + assertThat(ip4Address.toString(), is("255.255.255.255")); | ||
329 | + } | ||
330 | +} |
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import org.junit.Test; | ||
4 | + | ||
5 | +import static org.hamcrest.Matchers.equalTo; | ||
6 | +import static org.hamcrest.Matchers.is; | ||
7 | +import static org.hamcrest.Matchers.not; | ||
8 | +import static org.junit.Assert.assertThat; | ||
9 | +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; | ||
10 | + | ||
11 | +/** | ||
12 | + * Tests for class {@link Ip4Prefix}. | ||
13 | + */ | ||
14 | +public class Ip4PrefixTest { | ||
15 | + /** | ||
16 | + * Tests the immutability of {@link Ip4Prefix}. | ||
17 | + */ | ||
18 | + @Test | ||
19 | + public void testImmutable() { | ||
20 | + assertThatClassIsImmutable(Ip4Prefix.class); | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * Tests default class constructor. | ||
25 | + */ | ||
26 | + @Test | ||
27 | + public void testDefaultConstructor() { | ||
28 | + Ip4Prefix ip4prefix = new Ip4Prefix(); | ||
29 | + assertThat(ip4prefix.toString(), is("0.0.0.0/0")); | ||
30 | + } | ||
31 | + | ||
32 | + /** | ||
33 | + * Tests valid class copy constructor. | ||
34 | + */ | ||
35 | + @Test | ||
36 | + public void testCopyConstructor() { | ||
37 | + Ip4Prefix fromAddr = new Ip4Prefix("1.2.3.0/24"); | ||
38 | + Ip4Prefix ip4prefix = new Ip4Prefix(fromAddr); | ||
39 | + assertThat(ip4prefix.toString(), is("1.2.3.0/24")); | ||
40 | + | ||
41 | + fromAddr = new Ip4Prefix("0.0.0.0/0"); | ||
42 | + ip4prefix = new Ip4Prefix(fromAddr); | ||
43 | + assertThat(ip4prefix.toString(), is("0.0.0.0/0")); | ||
44 | + | ||
45 | + fromAddr = new Ip4Prefix("255.255.255.255/32"); | ||
46 | + ip4prefix = new Ip4Prefix(fromAddr); | ||
47 | + assertThat(ip4prefix.toString(), is("255.255.255.255/32")); | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * Tests invalid class copy constructor for a null object to copy from. | ||
52 | + */ | ||
53 | + @Test(expected = NullPointerException.class) | ||
54 | + public void testInvalidConstructorNullObject() { | ||
55 | + Ip4Prefix fromAddr = null; | ||
56 | + Ip4Prefix ip4prefix = new Ip4Prefix(fromAddr); | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Tests valid class constructor for an address and prefix length. | ||
61 | + */ | ||
62 | + @Test | ||
63 | + public void testConstructorForAddressAndPrefixLength() { | ||
64 | + Ip4Prefix ip4prefix = | ||
65 | + new Ip4Prefix(new Ip4Address("1.2.3.0"), (short) 24); | ||
66 | + assertThat(ip4prefix.toString(), is("1.2.3.0/24")); | ||
67 | + | ||
68 | + ip4prefix = new Ip4Prefix(new Ip4Address("1.2.3.4"), (short) 24); | ||
69 | + assertThat(ip4prefix.toString(), is("1.2.3.0/24")); | ||
70 | + | ||
71 | + ip4prefix = new Ip4Prefix(new Ip4Address("1.2.3.5"), (short) 32); | ||
72 | + assertThat(ip4prefix.toString(), is("1.2.3.5/32")); | ||
73 | + | ||
74 | + ip4prefix = new Ip4Prefix(new Ip4Address("0.0.0.0"), (short) 0); | ||
75 | + assertThat(ip4prefix.toString(), is("0.0.0.0/0")); | ||
76 | + | ||
77 | + ip4prefix = | ||
78 | + new Ip4Prefix(new Ip4Address("255.255.255.255"), (short) 32); | ||
79 | + assertThat(ip4prefix.toString(), is("255.255.255.255/32")); | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * Tests valid class constructor for a string. | ||
84 | + */ | ||
85 | + @Test | ||
86 | + public void testConstructorForString() { | ||
87 | + Ip4Prefix ip4prefix = new Ip4Prefix("1.2.3.0/24"); | ||
88 | + assertThat(ip4prefix.toString(), is("1.2.3.0/24")); | ||
89 | + | ||
90 | + ip4prefix = new Ip4Prefix("1.2.3.4/24"); | ||
91 | + assertThat(ip4prefix.toString(), is("1.2.3.0/24")); | ||
92 | + | ||
93 | + ip4prefix = new Ip4Prefix("1.2.3.5/32"); | ||
94 | + assertThat(ip4prefix.toString(), is("1.2.3.5/32")); | ||
95 | + | ||
96 | + ip4prefix = new Ip4Prefix("0.0.0.0/0"); | ||
97 | + assertThat(ip4prefix.toString(), is("0.0.0.0/0")); | ||
98 | + | ||
99 | + ip4prefix = new Ip4Prefix("255.255.255.255/32"); | ||
100 | + assertThat(ip4prefix.toString(), is("255.255.255.255/32")); | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * Tests invalid class constructor for a null string. | ||
105 | + */ | ||
106 | + @Test(expected = NullPointerException.class) | ||
107 | + public void testInvalidConstructorNullString() { | ||
108 | + String fromString = null; | ||
109 | + Ip4Prefix ip4prefix = new Ip4Prefix(fromString); | ||
110 | + } | ||
111 | + | ||
112 | + /** | ||
113 | + * Tests invalid class constructor for an empty string. | ||
114 | + */ | ||
115 | + @Test(expected = IllegalArgumentException.class) | ||
116 | + public void testInvalidConstructors() { | ||
117 | + // Check constructor for invalid ID: empty string | ||
118 | + Ip4Prefix ip4prefix = new Ip4Prefix(""); | ||
119 | + } | ||
120 | + | ||
121 | + /** | ||
122 | + * Tests getting the value of an address. | ||
123 | + */ | ||
124 | + @Test | ||
125 | + public void testGetValue() { | ||
126 | + Ip4Prefix ip4prefix = new Ip4Prefix("1.2.3.0/24"); | ||
127 | + assertThat(ip4prefix.getAddress(), equalTo(new Ip4Address("1.2.3.0"))); | ||
128 | + assertThat(ip4prefix.getPrefixLen(), is((short) 24)); | ||
129 | + | ||
130 | + ip4prefix = new Ip4Prefix("0.0.0.0/0"); | ||
131 | + assertThat(ip4prefix.getAddress(), equalTo(new Ip4Address("0.0.0.0"))); | ||
132 | + assertThat(ip4prefix.getPrefixLen(), is((short) 0)); | ||
133 | + | ||
134 | + ip4prefix = new Ip4Prefix("255.255.255.255/32"); | ||
135 | + assertThat(ip4prefix.getAddress(), | ||
136 | + equalTo(new Ip4Address("255.255.255.255"))); | ||
137 | + assertThat(ip4prefix.getPrefixLen(), is((short) 32)); | ||
138 | + } | ||
139 | + | ||
140 | + /** | ||
141 | + * Tests equality of {@link Ip4Address}. | ||
142 | + */ | ||
143 | + @Test | ||
144 | + public void testEquality() { | ||
145 | + Ip4Prefix addr1net = new Ip4Prefix("1.2.3.0/24"); | ||
146 | + Ip4Prefix addr2net = new Ip4Prefix("1.2.3.0/24"); | ||
147 | + assertThat(addr1net, is(addr2net)); | ||
148 | + | ||
149 | + addr1net = new Ip4Prefix("1.2.3.0/24"); | ||
150 | + addr2net = new Ip4Prefix("1.2.3.4/24"); | ||
151 | + assertThat(addr1net, is(addr2net)); | ||
152 | + | ||
153 | + addr1net = new Ip4Prefix("0.0.0.0/0"); | ||
154 | + addr2net = new Ip4Prefix("0.0.0.0/0"); | ||
155 | + assertThat(addr1net, is(addr2net)); | ||
156 | + | ||
157 | + addr1net = new Ip4Prefix("255.255.255.255/32"); | ||
158 | + addr2net = new Ip4Prefix("255.255.255.255/32"); | ||
159 | + assertThat(addr1net, is(addr2net)); | ||
160 | + } | ||
161 | + | ||
162 | + /** | ||
163 | + * Tests non-equality of {@link Ip4Address}. | ||
164 | + */ | ||
165 | + @Test | ||
166 | + public void testNonEquality() { | ||
167 | + Ip4Prefix addr1net = new Ip4Prefix("1.2.0.0/16"); | ||
168 | + Ip4Prefix addr2net = new Ip4Prefix("1.3.0.0/16"); | ||
169 | + Ip4Prefix addr3net = new Ip4Prefix("1.3.0.0/24"); | ||
170 | + Ip4Prefix addr4net = new Ip4Prefix("0.0.0.0/0"); | ||
171 | + Ip4Prefix addr5net = new Ip4Prefix("255.255.255.255/32"); | ||
172 | + assertThat(addr1net, is(not(addr2net))); | ||
173 | + assertThat(addr3net, is(not(addr2net))); | ||
174 | + assertThat(addr4net, is(not(addr2net))); | ||
175 | + assertThat(addr5net, is(not(addr2net))); | ||
176 | + } | ||
177 | + | ||
178 | + /** | ||
179 | + * Tests object string representation. | ||
180 | + */ | ||
181 | + @Test | ||
182 | + public void testToString() { | ||
183 | + Ip4Prefix ip4prefix = new Ip4Prefix("1.2.3.0/24"); | ||
184 | + assertThat(ip4prefix.toString(), is("1.2.3.0/24")); | ||
185 | + | ||
186 | + ip4prefix = new Ip4Prefix("1.2.3.4/24"); | ||
187 | + assertThat(ip4prefix.toString(), is("1.2.3.0/24")); | ||
188 | + | ||
189 | + ip4prefix = new Ip4Prefix("0.0.0.0/0"); | ||
190 | + assertThat(ip4prefix.toString(), is("0.0.0.0/0")); | ||
191 | + | ||
192 | + ip4prefix = new Ip4Prefix("255.255.255.255/32"); | ||
193 | + assertThat(ip4prefix.toString(), is("255.255.255.255/32")); | ||
194 | + } | ||
195 | +} |
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import org.junit.Test; | ||
4 | + | ||
5 | +import static org.hamcrest.Matchers.is; | ||
6 | +import static org.hamcrest.Matchers.not; | ||
7 | +import static org.junit.Assert.assertThat; | ||
8 | +import static org.junit.Assert.assertTrue; | ||
9 | +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; | ||
10 | + | ||
11 | +/** | ||
12 | + * Tests for class {@link Ip6Address}. | ||
13 | + */ | ||
14 | +public class Ip6AddressTest { | ||
15 | + /** | ||
16 | + * Tests the immutability of {@link Ip6Address}. | ||
17 | + */ | ||
18 | + @Test | ||
19 | + public void testImmutable() { | ||
20 | + assertThatClassIsImmutable(Ip6Address.class); | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * Tests the length of the address in bytes (octets). | ||
25 | + */ | ||
26 | + @Test | ||
27 | + public void testAddrBytelen() { | ||
28 | + assertThat(Ip6Address.BYTE_LENGTH, is(16)); | ||
29 | + } | ||
30 | + | ||
31 | + /** | ||
32 | + * Tests the length of the address in bits. | ||
33 | + */ | ||
34 | + @Test | ||
35 | + public void testAddrBitlen() { | ||
36 | + assertThat(Ip6Address.BIT_LENGTH, is(128)); | ||
37 | + } | ||
38 | + | ||
39 | + /** | ||
40 | + * Tests default class constructor. | ||
41 | + */ | ||
42 | + @Test | ||
43 | + public void testDefaultConstructor() { | ||
44 | + Ip6Address ip6Address = new Ip6Address(); | ||
45 | + assertThat(ip6Address.toString(), is("::")); | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Tests valid class copy constructor. | ||
50 | + */ | ||
51 | + @Test | ||
52 | + public void testCopyConstructor() { | ||
53 | + Ip6Address fromAddr = | ||
54 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
55 | + Ip6Address ip6Address = new Ip6Address(fromAddr); | ||
56 | + assertThat(ip6Address.toString(), | ||
57 | + is("1111:2222:3333:4444:5555:6666:7777:8888")); | ||
58 | + | ||
59 | + fromAddr = new Ip6Address("::"); | ||
60 | + ip6Address = new Ip6Address(fromAddr); | ||
61 | + assertThat(ip6Address.toString(), is("::")); | ||
62 | + | ||
63 | + fromAddr = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); | ||
64 | + ip6Address = new Ip6Address(fromAddr); | ||
65 | + assertThat(ip6Address.toString(), | ||
66 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); | ||
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * Tests invalid class copy constructor for a null object to copy from. | ||
71 | + */ | ||
72 | + @Test(expected = NullPointerException.class) | ||
73 | + public void testInvalidConstructorNullObject() { | ||
74 | + Ip6Address fromAddr = null; | ||
75 | + Ip6Address ip6Address = new Ip6Address(fromAddr); | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * Tests valid class constructor for integer values. | ||
80 | + */ | ||
81 | + @Test | ||
82 | + public void testConstructorForInteger() { | ||
83 | + Ip6Address ip6Address = | ||
84 | + new Ip6Address(0x1111222233334444L, 0x5555666677778888L); | ||
85 | + assertThat(ip6Address.toString(), | ||
86 | + is("1111:2222:3333:4444:5555:6666:7777:8888")); | ||
87 | + | ||
88 | + ip6Address = new Ip6Address(0L, 0L); | ||
89 | + assertThat(ip6Address.toString(), is("::")); | ||
90 | + | ||
91 | + ip6Address = new Ip6Address(-1L, -1L); | ||
92 | + assertThat(ip6Address.toString(), | ||
93 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); | ||
94 | + } | ||
95 | + | ||
96 | + /** | ||
97 | + * Tests valid class constructor for an array value. | ||
98 | + */ | ||
99 | + @Test | ||
100 | + public void testConstructorForArray() { | ||
101 | + final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22, | ||
102 | + 0x33, 0x33, 0x44, 0x44, | ||
103 | + 0x55, 0x55, 0x66, 0x66, | ||
104 | + 0x77, 0x77, | ||
105 | + (byte) 0x88, (byte) 0x88}; | ||
106 | + Ip6Address ip6Address = new Ip6Address(value1); | ||
107 | + assertThat(ip6Address.toString(), | ||
108 | + is("1111:2222:3333:4444:5555:6666:7777:8888")); | ||
109 | + | ||
110 | + final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00, | ||
111 | + 0x00, 0x00, 0x00, 0x00, | ||
112 | + 0x00, 0x00, 0x00, 0x00, | ||
113 | + 0x00, 0x00, 0x00, 0x00}; | ||
114 | + ip6Address = new Ip6Address(value2); | ||
115 | + assertThat(ip6Address.toString(), is("::")); | ||
116 | + | ||
117 | + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff, | ||
118 | + (byte) 0xff, (byte) 0xff, | ||
119 | + (byte) 0xff, (byte) 0xff, | ||
120 | + (byte) 0xff, (byte) 0xff, | ||
121 | + (byte) 0xff, (byte) 0xff, | ||
122 | + (byte) 0xff, (byte) 0xff, | ||
123 | + (byte) 0xff, (byte) 0xff, | ||
124 | + (byte) 0xff, (byte) 0xff}; | ||
125 | + ip6Address = new Ip6Address(value3); | ||
126 | + assertThat(ip6Address.toString(), | ||
127 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); | ||
128 | + } | ||
129 | + | ||
130 | + /** | ||
131 | + * Tests valid class constructor for an array value and an offset. | ||
132 | + */ | ||
133 | + @Test | ||
134 | + public void testConstructorForArrayAndOffset() { | ||
135 | + final byte[] value1 = new byte[] {11, 22, 33, // Preamble | ||
136 | + 0x11, 0x11, 0x22, 0x22, | ||
137 | + 0x33, 0x33, 0x44, 0x44, | ||
138 | + 0x55, 0x55, 0x66, 0x66, | ||
139 | + 0x77, 0x77, | ||
140 | + (byte) 0x88, (byte) 0x88, | ||
141 | + 44, 55}; // Extra bytes | ||
142 | + Ip6Address ip6Address = new Ip6Address(value1, 3); | ||
143 | + assertThat(ip6Address.toString(), | ||
144 | + is("1111:2222:3333:4444:5555:6666:7777:8888")); | ||
145 | + | ||
146 | + final byte[] value2 = new byte[] {11, 22, // Preamble | ||
147 | + 0x00, 0x00, 0x00, 0x00, | ||
148 | + 0x00, 0x00, 0x00, 0x00, | ||
149 | + 0x00, 0x00, 0x00, 0x00, | ||
150 | + 0x00, 0x00, 0x00, 0x00, | ||
151 | + 33}; // Extra bytes | ||
152 | + ip6Address = new Ip6Address(value2, 2); | ||
153 | + assertThat(ip6Address.toString(), is("::")); | ||
154 | + | ||
155 | + final byte[] value3 = new byte[] {11, 22, // Preamble | ||
156 | + (byte) 0xff, (byte) 0xff, | ||
157 | + (byte) 0xff, (byte) 0xff, | ||
158 | + (byte) 0xff, (byte) 0xff, | ||
159 | + (byte) 0xff, (byte) 0xff, | ||
160 | + (byte) 0xff, (byte) 0xff, | ||
161 | + (byte) 0xff, (byte) 0xff, | ||
162 | + (byte) 0xff, (byte) 0xff, | ||
163 | + (byte) 0xff, (byte) 0xff, | ||
164 | + 33}; // Extra bytes | ||
165 | + ip6Address = new Ip6Address(value3, 2); | ||
166 | + assertThat(ip6Address.toString(), | ||
167 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); | ||
168 | + } | ||
169 | + | ||
170 | + /** | ||
171 | + * Tests invalid class constructor for a null array. | ||
172 | + */ | ||
173 | + @Test(expected = NullPointerException.class) | ||
174 | + public void testInvalidConstructorNullArray() { | ||
175 | + final byte[] fromArray = null; | ||
176 | + Ip6Address ip6Address = new Ip6Address(fromArray); | ||
177 | + } | ||
178 | + | ||
179 | + /** | ||
180 | + * Tests invalid class constructor for an array that is too short. | ||
181 | + */ | ||
182 | + @Test(expected = IllegalArgumentException.class) | ||
183 | + public void testInvalidConstructorShortArray() { | ||
184 | + final byte[] fromArray = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}; | ||
185 | + Ip6Address ip6Address = new Ip6Address(fromArray); | ||
186 | + } | ||
187 | + | ||
188 | + /** | ||
189 | + * Tests invalid class constructor for an array and an invalid offset. | ||
190 | + */ | ||
191 | + @Test(expected = IllegalArgumentException.class) | ||
192 | + public void testInvalidConstructorArrayInvalidOffset() { | ||
193 | + final byte[] value1 = new byte[] {11, 22, 33, // Preamble | ||
194 | + 0x11, 0x11, 0x22, 0x22, | ||
195 | + 0x33, 0x33, 0x44, 0x44, | ||
196 | + 0x55, 0x55, 0x66, 0x66, | ||
197 | + 0x77, 0x77, | ||
198 | + (byte) 0x88, (byte) 0x88, | ||
199 | + 44, 55}; // Extra bytes | ||
200 | + Ip6Address ip6Address = new Ip6Address(value1, 6); | ||
201 | + } | ||
202 | + | ||
203 | + /** | ||
204 | + * Tests valid class constructor for a string. | ||
205 | + */ | ||
206 | + @Test | ||
207 | + public void testConstructorForString() { | ||
208 | + Ip6Address ip6Address = | ||
209 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
210 | + assertThat(ip6Address.toString(), | ||
211 | + is("1111:2222:3333:4444:5555:6666:7777:8888")); | ||
212 | + | ||
213 | + ip6Address = new Ip6Address("::"); | ||
214 | + assertThat(ip6Address.toString(), is("::")); | ||
215 | + | ||
216 | + ip6Address = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); | ||
217 | + assertThat(ip6Address.toString(), | ||
218 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); | ||
219 | + } | ||
220 | + | ||
221 | + /** | ||
222 | + * Tests invalid class constructor for a null string. | ||
223 | + */ | ||
224 | + @Test(expected = NullPointerException.class) | ||
225 | + public void testInvalidConstructorNullString() { | ||
226 | + String fromString = null; | ||
227 | + Ip6Address ip6Address = new Ip6Address(fromString); | ||
228 | + } | ||
229 | + | ||
230 | + /** | ||
231 | + * Tests invalid class constructor for an empty string. | ||
232 | + */ | ||
233 | + @Test(expected = IllegalArgumentException.class) | ||
234 | + public void testInvalidConstructors() { | ||
235 | + // Check constructor for invalid ID: empty string | ||
236 | + Ip6Address ip6Address = new Ip6Address(""); | ||
237 | + } | ||
238 | + | ||
239 | + /** | ||
240 | + * Tests returning the address as a byte array. | ||
241 | + */ | ||
242 | + @Test | ||
243 | + public void testAddressToOctets() { | ||
244 | + final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22, | ||
245 | + 0x33, 0x33, 0x44, 0x44, | ||
246 | + 0x55, 0x55, 0x66, 0x66, | ||
247 | + 0x77, 0x77, | ||
248 | + (byte) 0x88, (byte) 0x88}; | ||
249 | + Ip6Address ip6Address = | ||
250 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
251 | + assertThat(ip6Address.toOctets(), is(value1)); | ||
252 | + | ||
253 | + final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00, | ||
254 | + 0x00, 0x00, 0x00, 0x00, | ||
255 | + 0x00, 0x00, 0x00, 0x00, | ||
256 | + 0x00, 0x00, 0x00, 0x00}; | ||
257 | + ip6Address = new Ip6Address("::"); | ||
258 | + assertThat(ip6Address.toOctets(), is(value2)); | ||
259 | + | ||
260 | + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff, | ||
261 | + (byte) 0xff, (byte) 0xff, | ||
262 | + (byte) 0xff, (byte) 0xff, | ||
263 | + (byte) 0xff, (byte) 0xff, | ||
264 | + (byte) 0xff, (byte) 0xff, | ||
265 | + (byte) 0xff, (byte) 0xff, | ||
266 | + (byte) 0xff, (byte) 0xff, | ||
267 | + (byte) 0xff, (byte) 0xff}; | ||
268 | + ip6Address = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); | ||
269 | + assertThat(ip6Address.toOctets(), is(value3)); | ||
270 | + } | ||
271 | + | ||
272 | + /** | ||
273 | + * Tests making a mask prefix for a given prefix length. | ||
274 | + */ | ||
275 | + @Test | ||
276 | + public void testMakeMaskPrefix() { | ||
277 | + Ip6Address ip6Address = Ip6Address.makeMaskPrefix(8); | ||
278 | + assertThat(ip6Address.toString(), is("ff00::")); | ||
279 | + | ||
280 | + ip6Address = Ip6Address.makeMaskPrefix(120); | ||
281 | + assertThat(ip6Address.toString(), | ||
282 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00")); | ||
283 | + | ||
284 | + ip6Address = Ip6Address.makeMaskPrefix(0); | ||
285 | + assertThat(ip6Address.toString(), is("::")); | ||
286 | + | ||
287 | + ip6Address = Ip6Address.makeMaskPrefix(128); | ||
288 | + assertThat(ip6Address.toString(), | ||
289 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); | ||
290 | + | ||
291 | + ip6Address = Ip6Address.makeMaskPrefix(64); | ||
292 | + assertThat(ip6Address.toString(), is("ffff:ffff:ffff:ffff::")); | ||
293 | + } | ||
294 | + | ||
295 | + /** | ||
296 | + * Tests making of a masked address. | ||
297 | + */ | ||
298 | + @Test | ||
299 | + public void testMakeMaskedAddress() { | ||
300 | + Ip6Address ip6Address = | ||
301 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"); | ||
302 | + Ip6Address ip6AddressMasked = | ||
303 | + Ip6Address.makeMaskedAddress(ip6Address, 8); | ||
304 | + assertThat(ip6AddressMasked.toString(), is("1100::")); | ||
305 | + | ||
306 | + ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 120); | ||
307 | + assertThat(ip6AddressMasked.toString(), | ||
308 | + is("1111:2222:3333:4444:5555:6666:7777:8800")); | ||
309 | + | ||
310 | + ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 0); | ||
311 | + assertThat(ip6AddressMasked.toString(), is("::")); | ||
312 | + | ||
313 | + ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 128); | ||
314 | + assertThat(ip6AddressMasked.toString(), | ||
315 | + is("1111:2222:3333:4444:5555:6666:7777:8885")); | ||
316 | + | ||
317 | + ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 64); | ||
318 | + assertThat(ip6AddressMasked.toString(), is("1111:2222:3333:4444::")); | ||
319 | + } | ||
320 | + | ||
321 | + /** | ||
322 | + * Tests getting the value of an address. | ||
323 | + */ | ||
324 | + @Test | ||
325 | + public void testGetValue() { | ||
326 | + Ip6Address ip6Address = | ||
327 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
328 | + assertThat(ip6Address.getValueHigh(), is(0x1111222233334444L)); | ||
329 | + assertThat(ip6Address.getValueLow(), is(0x5555666677778888L)); | ||
330 | + | ||
331 | + ip6Address = new Ip6Address(0, 0); | ||
332 | + assertThat(ip6Address.getValueHigh(), is(0L)); | ||
333 | + assertThat(ip6Address.getValueLow(), is(0L)); | ||
334 | + | ||
335 | + ip6Address = new Ip6Address(-1L, -1L); | ||
336 | + assertThat(ip6Address.getValueHigh(), is(-1L)); | ||
337 | + assertThat(ip6Address.getValueLow(), is(-1L)); | ||
338 | + } | ||
339 | + | ||
340 | + /** | ||
341 | + * Tests equality of {@link Ip6Address}. | ||
342 | + */ | ||
343 | + @Test | ||
344 | + public void testEquality() { | ||
345 | + Ip6Address addr1 = | ||
346 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
347 | + Ip6Address addr2 = | ||
348 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
349 | + assertThat(addr1, is(addr2)); | ||
350 | + | ||
351 | + addr1 = new Ip6Address("::"); | ||
352 | + addr2 = new Ip6Address("::"); | ||
353 | + assertThat(addr1, is(addr2)); | ||
354 | + | ||
355 | + addr1 = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); | ||
356 | + addr2 = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); | ||
357 | + assertThat(addr1, is(addr2)); | ||
358 | + } | ||
359 | + | ||
360 | + /** | ||
361 | + * Tests non-equality of {@link Ip6Address}. | ||
362 | + */ | ||
363 | + @Test | ||
364 | + public void testNonEquality() { | ||
365 | + Ip6Address addr1 = | ||
366 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
367 | + Ip6Address addr2 = | ||
368 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:888A"); | ||
369 | + Ip6Address addr3 = new Ip6Address("::"); | ||
370 | + Ip6Address addr4 = | ||
371 | + new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); | ||
372 | + assertThat(addr1, is(not(addr2))); | ||
373 | + assertThat(addr3, is(not(addr2))); | ||
374 | + assertThat(addr4, is(not(addr2))); | ||
375 | + } | ||
376 | + | ||
377 | + /** | ||
378 | + * Tests comparison of {@link Ip6Address}. | ||
379 | + */ | ||
380 | + @Test | ||
381 | + public void testComparison() { | ||
382 | + Ip6Address addr1 = | ||
383 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
384 | + Ip6Address addr2 = | ||
385 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
386 | + Ip6Address addr3 = | ||
387 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8887"); | ||
388 | + Ip6Address addr4 = | ||
389 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8889"); | ||
390 | + assertTrue(addr1.compareTo(addr2) == 0); | ||
391 | + assertTrue(addr1.compareTo(addr3) > 0); | ||
392 | + assertTrue(addr1.compareTo(addr4) < 0); | ||
393 | + | ||
394 | + addr1 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888"); | ||
395 | + addr2 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888"); | ||
396 | + addr3 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8887"); | ||
397 | + addr4 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8889"); | ||
398 | + assertTrue(addr1.compareTo(addr2) == 0); | ||
399 | + assertTrue(addr1.compareTo(addr3) > 0); | ||
400 | + assertTrue(addr1.compareTo(addr4) < 0); | ||
401 | + | ||
402 | + addr1 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888"); | ||
403 | + addr2 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888"); | ||
404 | + addr3 = new Ip6Address("ffff:2222:3333:4443:5555:6666:7777:8888"); | ||
405 | + addr4 = new Ip6Address("ffff:2222:3333:4445:5555:6666:7777:8888"); | ||
406 | + assertTrue(addr1.compareTo(addr2) == 0); | ||
407 | + assertTrue(addr1.compareTo(addr3) > 0); | ||
408 | + assertTrue(addr1.compareTo(addr4) < 0); | ||
409 | + } | ||
410 | + | ||
411 | + /** | ||
412 | + * Tests object string representation. | ||
413 | + */ | ||
414 | + @Test | ||
415 | + public void testToString() { | ||
416 | + Ip6Address ip6Address = | ||
417 | + new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888"); | ||
418 | + assertThat(ip6Address.toString(), | ||
419 | + is("1111:2222:3333:4444:5555:6666:7777:8888")); | ||
420 | + | ||
421 | + ip6Address = new Ip6Address("1111::8888"); | ||
422 | + assertThat(ip6Address.toString(), is("1111::8888")); | ||
423 | + | ||
424 | + ip6Address = new Ip6Address("1111::"); | ||
425 | + assertThat(ip6Address.toString(), is("1111::")); | ||
426 | + | ||
427 | + ip6Address = new Ip6Address("::8888"); | ||
428 | + assertThat(ip6Address.toString(), is("::8888")); | ||
429 | + | ||
430 | + ip6Address = new Ip6Address("::"); | ||
431 | + assertThat(ip6Address.toString(), is("::")); | ||
432 | + | ||
433 | + ip6Address = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); | ||
434 | + assertThat(ip6Address.toString(), | ||
435 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); | ||
436 | + } | ||
437 | +} |
1 | +package org.onlab.packet; | ||
2 | + | ||
3 | +import org.junit.Test; | ||
4 | + | ||
5 | +import static org.hamcrest.Matchers.equalTo; | ||
6 | +import static org.hamcrest.Matchers.is; | ||
7 | +import static org.hamcrest.Matchers.not; | ||
8 | +import static org.junit.Assert.assertThat; | ||
9 | +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; | ||
10 | + | ||
11 | +/** | ||
12 | + * Tests for class {@link Ip6Prefix}. | ||
13 | + */ | ||
14 | +public class Ip6PrefixTest { | ||
15 | + /** | ||
16 | + * Tests the immutability of {@link Ip6Prefix}. | ||
17 | + */ | ||
18 | + @Test | ||
19 | + public void testImmutable() { | ||
20 | + assertThatClassIsImmutable(Ip6Prefix.class); | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * Tests default class constructor. | ||
25 | + */ | ||
26 | + @Test | ||
27 | + public void testDefaultConstructor() { | ||
28 | + Ip6Prefix ip6prefix = new Ip6Prefix(); | ||
29 | + assertThat(ip6prefix.toString(), is("::/0")); | ||
30 | + } | ||
31 | + | ||
32 | + /** | ||
33 | + * Tests valid class copy constructor. | ||
34 | + */ | ||
35 | + @Test | ||
36 | + public void testCopyConstructor() { | ||
37 | + Ip6Prefix fromAddr = new Ip6Prefix("1100::/8"); | ||
38 | + Ip6Prefix ip6prefix = new Ip6Prefix(fromAddr); | ||
39 | + assertThat(ip6prefix.toString(), is("1100::/8")); | ||
40 | + | ||
41 | + fromAddr = new Ip6Prefix("::/0"); | ||
42 | + ip6prefix = new Ip6Prefix(fromAddr); | ||
43 | + assertThat(ip6prefix.toString(), is("::/0")); | ||
44 | + | ||
45 | + fromAddr = | ||
46 | + new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); | ||
47 | + ip6prefix = new Ip6Prefix(fromAddr); | ||
48 | + assertThat(ip6prefix.toString(), | ||
49 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")); | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * Tests invalid class copy constructor for a null object to copy from. | ||
54 | + */ | ||
55 | + @Test(expected = NullPointerException.class) | ||
56 | + public void testInvalidConstructorNullObject() { | ||
57 | + Ip6Prefix fromAddr = null; | ||
58 | + Ip6Prefix ip6prefix = new Ip6Prefix(fromAddr); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Tests valid class constructor for an address and prefix length. | ||
63 | + */ | ||
64 | + @Test | ||
65 | + public void testConstructorForAddressAndPrefixLength() { | ||
66 | + Ip6Prefix ip6prefix = | ||
67 | + new Ip6Prefix(new Ip6Address("1100::"), (short) 8); | ||
68 | + assertThat(ip6prefix.toString(), is("1100::/8")); | ||
69 | + | ||
70 | + ip6prefix = | ||
71 | + new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"), | ||
72 | + (short) 8); | ||
73 | + assertThat(ip6prefix.toString(), is("1100::/8")); | ||
74 | + | ||
75 | + ip6prefix = | ||
76 | + new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8800"), | ||
77 | + (short) 120); | ||
78 | + assertThat(ip6prefix.toString(), | ||
79 | + is("1111:2222:3333:4444:5555:6666:7777:8800/120")); | ||
80 | + | ||
81 | + ip6prefix = new Ip6Prefix(new Ip6Address("::"), (short) 0); | ||
82 | + assertThat(ip6prefix.toString(), is("::/0")); | ||
83 | + | ||
84 | + ip6prefix = | ||
85 | + new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"), | ||
86 | + (short) 128); | ||
87 | + assertThat(ip6prefix.toString(), | ||
88 | + is("1111:2222:3333:4444:5555:6666:7777:8885/128")); | ||
89 | + | ||
90 | + ip6prefix = | ||
91 | + new Ip6Prefix(new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), | ||
92 | + (short) 128); | ||
93 | + assertThat(ip6prefix.toString(), | ||
94 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")); | ||
95 | + | ||
96 | + ip6prefix = | ||
97 | + new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"), | ||
98 | + (short) 64); | ||
99 | + assertThat(ip6prefix.toString(), is("1111:2222:3333:4444::/64")); | ||
100 | + } | ||
101 | + | ||
102 | + /** | ||
103 | + * Tests valid class constructor for a string. | ||
104 | + */ | ||
105 | + @Test | ||
106 | + public void testConstructorForString() { | ||
107 | + Ip6Prefix ip6prefix = new Ip6Prefix("1100::/8"); | ||
108 | + assertThat(ip6prefix.toString(), is("1100::/8")); | ||
109 | + | ||
110 | + ip6prefix = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8"); | ||
111 | + assertThat(ip6prefix.toString(), is("1100::/8")); | ||
112 | + | ||
113 | + ip6prefix = | ||
114 | + new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8800/120"); | ||
115 | + assertThat(ip6prefix.toString(), | ||
116 | + is("1111:2222:3333:4444:5555:6666:7777:8800/120")); | ||
117 | + | ||
118 | + ip6prefix = new Ip6Prefix("::/0"); | ||
119 | + assertThat(ip6prefix.toString(), is("::/0")); | ||
120 | + | ||
121 | + ip6prefix = | ||
122 | + new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/128"); | ||
123 | + assertThat(ip6prefix.toString(), | ||
124 | + is("1111:2222:3333:4444:5555:6666:7777:8885/128")); | ||
125 | + | ||
126 | + ip6prefix = new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); | ||
127 | + assertThat(ip6prefix.toString(), | ||
128 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")); | ||
129 | + | ||
130 | + ip6prefix = | ||
131 | + new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/64"); | ||
132 | + assertThat(ip6prefix.toString(), is("1111:2222:3333:4444::/64")); | ||
133 | + } | ||
134 | + | ||
135 | + /** | ||
136 | + * Tests invalid class constructor for a null string. | ||
137 | + */ | ||
138 | + @Test(expected = NullPointerException.class) | ||
139 | + public void testInvalidConstructorNullString() { | ||
140 | + String fromString = null; | ||
141 | + Ip6Prefix ip6prefix = new Ip6Prefix(fromString); | ||
142 | + } | ||
143 | + | ||
144 | + /** | ||
145 | + * Tests invalid class constructor for an empty string. | ||
146 | + */ | ||
147 | + @Test(expected = IllegalArgumentException.class) | ||
148 | + public void testInvalidConstructors() { | ||
149 | + // Check constructor for invalid ID: empty string | ||
150 | + Ip6Prefix ip6prefix = new Ip6Prefix(""); | ||
151 | + } | ||
152 | + | ||
153 | + /** | ||
154 | + * Tests getting the value of an address. | ||
155 | + */ | ||
156 | + @Test | ||
157 | + public void testGetValue() { | ||
158 | + Ip6Prefix ip6prefix = new Ip6Prefix("1100::/8"); | ||
159 | + assertThat(ip6prefix.getAddress(), equalTo(new Ip6Address("1100::"))); | ||
160 | + assertThat(ip6prefix.getPrefixLen(), is((short) 8)); | ||
161 | + | ||
162 | + ip6prefix = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8"); | ||
163 | + assertThat(ip6prefix.getAddress(), equalTo(new Ip6Address("1100::"))); | ||
164 | + assertThat(ip6prefix.getPrefixLen(), is((short) 8)); | ||
165 | + | ||
166 | + ip6prefix = | ||
167 | + new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8800/120"); | ||
168 | + assertThat(ip6prefix.getAddress(), | ||
169 | + equalTo(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8800"))); | ||
170 | + assertThat(ip6prefix.getPrefixLen(), is((short) 120)); | ||
171 | + | ||
172 | + ip6prefix = new Ip6Prefix("::/0"); | ||
173 | + assertThat(ip6prefix.getAddress(), equalTo(new Ip6Address("::"))); | ||
174 | + assertThat(ip6prefix.getPrefixLen(), is((short) 0)); | ||
175 | + | ||
176 | + ip6prefix = | ||
177 | + new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/128"); | ||
178 | + assertThat(ip6prefix.getAddress(), | ||
179 | + equalTo(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"))); | ||
180 | + assertThat(ip6prefix.getPrefixLen(), is((short) 128)); | ||
181 | + | ||
182 | + ip6prefix = | ||
183 | + new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); | ||
184 | + assertThat(ip6prefix.getAddress(), | ||
185 | + equalTo(new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))); | ||
186 | + assertThat(ip6prefix.getPrefixLen(), is((short) 128)); | ||
187 | + | ||
188 | + ip6prefix = | ||
189 | + new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/64"); | ||
190 | + assertThat(ip6prefix.getAddress(), | ||
191 | + equalTo(new Ip6Address("1111:2222:3333:4444::"))); | ||
192 | + assertThat(ip6prefix.getPrefixLen(), is((short) 64)); | ||
193 | + } | ||
194 | + | ||
195 | + /** | ||
196 | + * Tests equality of {@link Ip6Address}. | ||
197 | + */ | ||
198 | + @Test | ||
199 | + public void testEquality() { | ||
200 | + Ip6Prefix addr1net = new Ip6Prefix("1100::/8"); | ||
201 | + Ip6Prefix addr2net = new Ip6Prefix("1100::/8"); | ||
202 | + assertThat(addr1net, is(addr2net)); | ||
203 | + | ||
204 | + addr1net = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8"); | ||
205 | + addr2net = new Ip6Prefix("1100::/8"); | ||
206 | + assertThat(addr1net, is(addr2net)); | ||
207 | + | ||
208 | + addr1net = new Ip6Prefix("::/0"); | ||
209 | + addr2net = new Ip6Prefix("::/0"); | ||
210 | + assertThat(addr1net, is(addr2net)); | ||
211 | + | ||
212 | + addr1net = | ||
213 | + new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); | ||
214 | + addr2net = | ||
215 | + new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); | ||
216 | + assertThat(addr1net, is(addr2net)); | ||
217 | + } | ||
218 | + | ||
219 | + /** | ||
220 | + * Tests non-equality of {@link Ip6Address}. | ||
221 | + */ | ||
222 | + @Test | ||
223 | + public void testNonEquality() { | ||
224 | + Ip6Prefix addr1net = new Ip6Prefix("1100::/8"); | ||
225 | + Ip6Prefix addr2net = new Ip6Prefix("1200::/8"); | ||
226 | + Ip6Prefix addr3net = new Ip6Prefix("1200::/12"); | ||
227 | + Ip6Prefix addr4net = new Ip6Prefix("::/0"); | ||
228 | + Ip6Prefix addr5net = | ||
229 | + new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); | ||
230 | + assertThat(addr1net, is(not(addr2net))); | ||
231 | + assertThat(addr3net, is(not(addr2net))); | ||
232 | + assertThat(addr4net, is(not(addr2net))); | ||
233 | + assertThat(addr5net, is(not(addr2net))); | ||
234 | + } | ||
235 | + | ||
236 | + /** | ||
237 | + * Tests object string representation. | ||
238 | + */ | ||
239 | + @Test | ||
240 | + public void testToString() { | ||
241 | + Ip6Prefix ip6prefix = new Ip6Prefix("1100::/8"); | ||
242 | + assertThat(ip6prefix.toString(), is("1100::/8")); | ||
243 | + | ||
244 | + ip6prefix = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8"); | ||
245 | + assertThat(ip6prefix.toString(), is("1100::/8")); | ||
246 | + | ||
247 | + ip6prefix = new Ip6Prefix("::/0"); | ||
248 | + assertThat(ip6prefix.toString(), is("::/0")); | ||
249 | + | ||
250 | + ip6prefix = | ||
251 | + new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); | ||
252 | + assertThat(ip6prefix.toString(), | ||
253 | + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128")); | ||
254 | + } | ||
255 | +} |
-
Please register or login to post a comment