Pavlin Radoslavov

Added support for IPv6 addresses to class IpAddress:

 - For some of the methods, the IP Version needs to be specified by the
   caller. This applies to the IpPrefix API as well.
 - For now, everywhere IpAddress is used and the IP version has to be
   explicitly specified by the caller, we assume/specify IPv4.
 - Added unit test for class IpAddress: for both IPv4 and IPv6 addresses.
...@@ -246,11 +246,13 @@ public class BgpSession extends SimpleChannelHandler { ...@@ -246,11 +246,13 @@ public class BgpSession extends SimpleChannelHandler {
246 InetAddress inetAddr; 246 InetAddress inetAddr;
247 if (localAddress instanceof InetSocketAddress) { 247 if (localAddress instanceof InetSocketAddress) {
248 inetAddr = ((InetSocketAddress) localAddress).getAddress(); 248 inetAddr = ((InetSocketAddress) localAddress).getAddress();
249 - localIp4Address = IpAddress.valueOf(inetAddr.getAddress()); 249 + localIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
250 + inetAddr.getAddress());
250 } 251 }
251 if (remoteAddress instanceof InetSocketAddress) { 252 if (remoteAddress instanceof InetSocketAddress) {
252 inetAddr = ((InetSocketAddress) remoteAddress).getAddress(); 253 inetAddr = ((InetSocketAddress) remoteAddress).getAddress();
253 - remoteIp4Address = IpAddress.valueOf(inetAddr.getAddress()); 254 + remoteIp4Address = IpAddress.valueOf(IpAddress.Version.INET,
255 + inetAddr.getAddress());
254 } 256 }
255 257
256 log.debug("BGP Session Connected from {} on {}", 258 log.debug("BGP Session Connected from {} on {}",
......
...@@ -105,7 +105,8 @@ public class BgpSessionManager { ...@@ -105,7 +105,8 @@ public class BgpSessionManager {
105 if (bgpSession.getLocalAddress() instanceof InetSocketAddress) { 105 if (bgpSession.getLocalAddress() instanceof InetSocketAddress) {
106 InetAddress inetAddr = 106 InetAddress inetAddr =
107 ((InetSocketAddress) bgpSession.getLocalAddress()).getAddress(); 107 ((InetSocketAddress) bgpSession.getLocalAddress()).getAddress();
108 - IpAddress ip4Address = IpAddress.valueOf(inetAddr.getAddress()); 108 + IpAddress ip4Address = IpAddress.valueOf(IpAddress.Version.INET,
109 + inetAddr.getAddress());
109 updateMyBgpId(ip4Address); 110 updateMyBgpId(ip4Address);
110 } 111 }
111 return true; 112 return true;
......
...@@ -132,7 +132,8 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -132,7 +132,8 @@ public class ProxyArpManager implements ProxyArpService {
132 // for one of our external addresses. 132 // for one of our external addresses.
133 if (isOutsidePort(inPort)) { 133 if (isOutsidePort(inPort)) {
134 IpAddress target = 134 IpAddress target =
135 - IpAddress.valueOf(arp.getTargetProtocolAddress()); 135 + IpAddress.valueOf(IpAddress.Version.INET,
136 + arp.getTargetProtocolAddress());
136 PortAddresses addresses = 137 PortAddresses addresses =
137 hostService.getAddressBindingsForPort(inPort); 138 hostService.getAddressBindingsForPort(inPort);
138 139
...@@ -149,7 +150,8 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -149,7 +150,8 @@ public class ProxyArpManager implements ProxyArpService {
149 // it could be a request from an internal host to an external 150 // it could be a request from an internal host to an external
150 // address. Forward it over to the correct port. 151 // address. Forward it over to the correct port.
151 IpAddress source = 152 IpAddress source =
152 - IpAddress.valueOf(arp.getSenderProtocolAddress()); 153 + IpAddress.valueOf(IpAddress.Version.INET,
154 + arp.getSenderProtocolAddress());
153 PortAddresses sourceAddresses = findPortInSubnet(source); 155 PortAddresses sourceAddresses = findPortInSubnet(source);
154 if (sourceAddresses != null) { 156 if (sourceAddresses != null) {
155 for (InterfaceIpAddress ia : sourceAddresses.ipAddresses()) { 157 for (InterfaceIpAddress ia : sourceAddresses.ipAddresses()) {
...@@ -164,8 +166,9 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -164,8 +166,9 @@ public class ProxyArpManager implements ProxyArpService {
164 // Continue with normal proxy ARP case 166 // Continue with normal proxy ARP case
165 167
166 VlanId vlan = VlanId.vlanId(eth.getVlanID()); 168 VlanId vlan = VlanId.vlanId(eth.getVlanID());
167 - Set<Host> hosts = hostService.getHostsByIp(IpAddress.valueOf(arp 169 + Set<Host> hosts =
168 - .getTargetProtocolAddress())); 170 + hostService.getHostsByIp(IpAddress.valueOf(IpAddress.Version.INET,
171 + arp.getTargetProtocolAddress()));
169 172
170 Host dst = null; 173 Host dst = null;
171 Host src = hostService.getHost(HostId.hostId(eth.getSourceMAC(), 174 Host src = hostService.getHost(HostId.hostId(eth.getSourceMAC(),
......
...@@ -148,7 +148,8 @@ public class DistributedClusterStore ...@@ -148,7 +148,8 @@ public class DistributedClusterStore
148 148
149 private IpAddress memberAddress(Member member) { 149 private IpAddress memberAddress(Member member) {
150 byte[] address = member.getSocketAddress().getAddress().getAddress(); 150 byte[] address = member.getSocketAddress().getAddress().getAddress();
151 - return IpAddress.valueOf(address); 151 + // TODO: Add support for IPv6
152 + return IpAddress.valueOf(IpAddress.Version.INET, address);
152 } 153 }
153 154
154 // Interceptor for membership events. 155 // Interceptor for membership events.
......
...@@ -46,7 +46,8 @@ public class IpAddressSerializer extends Serializer<IpAddress> { ...@@ -46,7 +46,8 @@ public class IpAddressSerializer extends Serializer<IpAddress> {
46 final int octLen = input.readInt(); 46 final int octLen = input.readInt();
47 byte[] octs = new byte[octLen]; 47 byte[] octs = new byte[octLen];
48 input.readBytes(octs); 48 input.readBytes(octs);
49 - return IpAddress.valueOf(octs); 49 + // TODO: Add support for reading/writing the IP version
50 + return IpAddress.valueOf(IpAddress.Version.INET, octs);
50 } 51 }
51 52
52 } 53 }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onlab.onos.store.serializers; 16 package org.onlab.onos.store.serializers;
17 17
18 +import org.onlab.packet.IpAddress;
18 import org.onlab.packet.IpPrefix; 19 import org.onlab.packet.IpPrefix;
19 20
20 import com.esotericsoftware.kryo.Kryo; 21 import com.esotericsoftware.kryo.Kryo;
...@@ -51,6 +52,7 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> { ...@@ -51,6 +52,7 @@ public final class IpPrefixSerializer extends Serializer<IpPrefix> {
51 byte[] octs = new byte[octLen]; 52 byte[] octs = new byte[octLen];
52 input.readBytes(octs); 53 input.readBytes(octs);
53 int prefLen = input.readInt(); 54 int prefLen = input.readInt();
54 - return IpPrefix.valueOf(octs, prefLen); 55 + // TODO: Add support for reading/writing the IP version
56 + return IpPrefix.valueOf(IpAddress.Version.INET, octs, prefLen);
55 } 57 }
56 } 58 }
......
...@@ -120,7 +120,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid ...@@ -120,7 +120,8 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid
120 if (eth.getEtherType() == Ethernet.TYPE_ARP) { 120 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
121 ARP arp = (ARP) eth.getPayload(); 121 ARP arp = (ARP) eth.getPayload();
122 IpAddress ip = 122 IpAddress ip =
123 - IpAddress.valueOf(arp.getSenderProtocolAddress()); 123 + IpAddress.valueOf(IpAddress.Version.INET,
124 + arp.getSenderProtocolAddress());
124 HostDescription hdescr = 125 HostDescription hdescr =
125 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip); 126 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
126 providerService.hostDetected(hid, hdescr); 127 providerService.hostDetected(hid, hdescr);
......
...@@ -145,7 +145,8 @@ public abstract class FlowModBuilder { ...@@ -145,7 +145,8 @@ public abstract class FlowModBuilder {
145 ip = (IPCriterion) c; 145 ip = (IPCriterion) c;
146 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) { 146 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) {
147 IpAddress maskAddr = 147 IpAddress maskAddr =
148 - IpAddress.makeMaskPrefix(ip.ip().prefixLength()); 148 + IpAddress.makeMaskPrefix(ip.ip().address().version(),
149 + ip.ip().prefixLength());
149 Masked<IPv4Address> maskedIp = 150 Masked<IPv4Address> maskedIp =
150 Masked.of(IPv4Address.of(ip.ip().address().toInt()), 151 Masked.of(IPv4Address.of(ip.ip().address().toInt()),
151 IPv4Address.of(maskAddr.toInt())); 152 IPv4Address.of(maskAddr.toInt()));
...@@ -159,7 +160,8 @@ public abstract class FlowModBuilder { ...@@ -159,7 +160,8 @@ public abstract class FlowModBuilder {
159 ip = (IPCriterion) c; 160 ip = (IPCriterion) c;
160 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) { 161 if (ip.ip().prefixLength() != IpPrefix.MAX_INET_MASK_LENGTH) {
161 IpAddress maskAddr = 162 IpAddress maskAddr =
162 - IpAddress.makeMaskPrefix(ip.ip().prefixLength()); 163 + IpAddress.makeMaskPrefix(ip.ip().address().version(),
164 + ip.ip().prefixLength());
163 Masked<IPv4Address> maskedIp = 165 Masked<IPv4Address> maskedIp =
164 Masked.of(IPv4Address.of(ip.ip().address().toInt()), 166 Masked.of(IPv4Address.of(ip.ip().address().toInt()),
165 IPv4Address.of(maskAddr.toInt())); 167 IPv4Address.of(maskAddr.toInt()));
......
...@@ -126,7 +126,8 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid ...@@ -126,7 +126,8 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid
126 if (eth.getEtherType() == Ethernet.TYPE_ARP) { 126 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
127 ARP arp = (ARP) eth.getPayload(); 127 ARP arp = (ARP) eth.getPayload();
128 IpAddress ip = 128 IpAddress ip =
129 - IpAddress.valueOf(arp.getSenderProtocolAddress()); 129 + IpAddress.valueOf(IpAddress.Version.INET,
130 + arp.getSenderProtocolAddress());
130 HostDescription hdescr = 131 HostDescription hdescr =
131 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip); 132 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
132 providerService.hostDetected(hid, hdescr); 133 providerService.hostDetected(hid, hdescr);
......
...@@ -15,10 +15,18 @@ ...@@ -15,10 +15,18 @@
15 */ 15 */
16 package org.onlab.packet; 16 package org.onlab.packet;
17 17
18 +import java.net.InetAddress;
19 +import java.net.Inet4Address;
20 +import java.net.Inet6Address;
21 +import java.net.UnknownHostException;
18 import java.nio.ByteBuffer; 22 import java.nio.ByteBuffer;
19 import java.util.Arrays; 23 import java.util.Arrays;
20 import java.util.Objects; 24 import java.util.Objects;
21 -import static com.google.common.base.Preconditions.checkNotNull; 25 +
26 +import com.google.common.net.InetAddresses;
27 +import com.google.common.primitives.UnsignedBytes;
28 +
29 +import static com.google.common.base.Preconditions.checkState;
22 30
23 /** 31 /**
24 * A class representing an IP address. 32 * A class representing an IP address.
...@@ -40,13 +48,74 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -40,13 +48,74 @@ public final class IpAddress implements Comparable<IpAddress> {
40 /** 48 /**
41 * Constructor for given IP address version and address octets. 49 * Constructor for given IP address version and address octets.
42 * 50 *
51 + * @param version the IP address version
43 * @param value the IP address value stored in network byte order 52 * @param value the IP address value stored in network byte order
44 * (i.e., the most significant byte first) 53 * (i.e., the most significant byte first)
45 - * @param value the IP address value 54 + * @throws IllegalArgumentException if the arguments are invalid
46 */ 55 */
47 private IpAddress(Version version, byte[] value) { 56 private IpAddress(Version version, byte[] value) {
57 + checkArguments(version, value, 0);
48 this.version = version; 58 this.version = version;
49 - this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH); 59 + switch (version) {
60 + case INET:
61 + this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH);
62 + break;
63 + case INET6:
64 + this.octets = Arrays.copyOf(value, INET6_BYTE_LENGTH);
65 + break;
66 + default:
67 + // Should not be reached
68 + this.octets = null;
69 + break;
70 + }
71 + }
72 +
73 + /**
74 + * Returns the IP version of this address.
75 + *
76 + * @return the version
77 + */
78 + public Version version() {
79 + return this.version;
80 + }
81 +
82 + /**
83 + * Returns the IP address as a byte array.
84 + *
85 + * @return a byte array
86 + */
87 + public byte[] toOctets() {
88 + return Arrays.copyOf(octets, octets.length);
89 + }
90 +
91 + /**
92 + * Returns the integral value of this IP address.
93 + * TODO: This method should be moved to Ip4Address.
94 + *
95 + * @return the IP address's value as an integer
96 + */
97 + public int toInt() {
98 + ByteBuffer bb = ByteBuffer.wrap(octets);
99 + return bb.getInt();
100 + }
101 +
102 + /**
103 + * Computes the IP address byte length for a given IP version.
104 + *
105 + * @param version the IP version
106 + * @return the IP address byte length for the IP version
107 + * @throws IllegalArgumentException if the IP version is invalid
108 + */
109 + public static int byteLength(Version version) {
110 + switch (version) {
111 + case INET:
112 + return INET_BYTE_LENGTH;
113 + case INET6:
114 + return INET6_BYTE_LENGTH;
115 + default:
116 + String msg = "Invalid IP version " + version;
117 + throw new IllegalArgumentException(msg);
118 + }
50 } 119 }
51 120
52 /** 121 /**
...@@ -64,13 +133,14 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -64,13 +133,14 @@ public final class IpAddress implements Comparable<IpAddress> {
64 /** 133 /**
65 * Converts a byte array into an IP address. 134 * Converts a byte array into an IP address.
66 * 135 *
136 + * @param version the IP address version
67 * @param value the IP address value stored in network byte order 137 * @param value the IP address value stored in network byte order
68 * (i.e., the most significant byte first) 138 * (i.e., the most significant byte first)
69 * @return an IP address 139 * @return an IP address
140 + * @throws IllegalArgumentException if the arguments are invalid
70 */ 141 */
71 - public static IpAddress valueOf(byte[] value) { 142 + public static IpAddress valueOf(Version version, byte[] value) {
72 - checkNotNull(value); 143 + return new IpAddress(version, value);
73 - return new IpAddress(Version.INET, value);
74 } 144 }
75 145
76 /** 146 /**
...@@ -80,96 +150,83 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -80,96 +150,83 @@ public final class IpAddress implements Comparable<IpAddress> {
80 * The IP address is stored in network byte order (i.e., the most 150 * The IP address is stored in network byte order (i.e., the most
81 * significant byte first). 151 * significant byte first).
82 * </p> 152 * </p>
153 + * @param version the IP address version
83 * @param value the value to use 154 * @param value the value to use
84 * @param offset the offset in bytes from the beginning of the byte array 155 * @param offset the offset in bytes from the beginning of the byte array
85 * @return an IP address 156 * @return an IP address
157 + * @throws IllegalArgumentException if the arguments are invalid
86 */ 158 */
87 - public static IpAddress valueOf(byte[] value, int offset) { 159 + public static IpAddress valueOf(Version version, byte[] value,
88 - // Verify the arguments 160 + int offset) {
89 - if ((offset < 0) || (offset + INET_BYTE_LENGTH > value.length)) { 161 + checkArguments(version, value, offset);
90 - String msg;
91 - if (value.length < INET_BYTE_LENGTH) {
92 - msg = "Invalid IPv4 address array: array length: " +
93 - value.length + ". Must be at least " + INET_BYTE_LENGTH;
94 - } else {
95 - msg = "Invalid IPv4 address array: array offset: " +
96 - offset + ". Must be in the interval [0, " +
97 - (value.length - INET_BYTE_LENGTH) + "]";
98 - }
99 - throw new IllegalArgumentException(msg);
100 - }
101 -
102 byte[] bc = Arrays.copyOfRange(value, offset, value.length); 162 byte[] bc = Arrays.copyOfRange(value, offset, value.length);
103 - return IpAddress.valueOf(bc); 163 + return IpAddress.valueOf(version, bc);
104 } 164 }
105 165
106 /** 166 /**
107 - * Converts a dotted-decimal string (x.x.x.x) into an IPv4 address. 167 + * Converts an IPv4 or IPv6 string literal (e.g., "10.2.3.4" or
168 + * "1111:2222::8888") into an IP address.
108 * 169 *
109 - * @param address an IP address in string form, e.g. "10.0.0.1" 170 + * @param value an IP address value in string form
110 * @return an IP address 171 * @return an IP address
172 + * @throws IllegalArgumentException if the argument is invalid
111 */ 173 */
112 - public static IpAddress valueOf(String address) { 174 + public static IpAddress valueOf(String value) {
113 - final String[] net = address.split("\\."); 175 + InetAddress addr = null;
114 - if (net.length != INET_BYTE_LENGTH) { 176 + try {
115 - String msg = "Malformed IPv4 address string: " + address + "." + 177 + addr = InetAddresses.forString(value);
116 - "Address must have four decimal values separated by dots (.)"; 178 + } catch (IllegalArgumentException e) {
179 + final String msg = "Invalid IP address string: " + value;
117 throw new IllegalArgumentException(msg); 180 throw new IllegalArgumentException(msg);
118 } 181 }
119 - final byte[] bytes = new byte[INET_BYTE_LENGTH]; 182 + byte[] bytes = addr.getAddress();
120 - for (int i = 0; i < INET_BYTE_LENGTH; i++) { 183 + if (addr instanceof Inet4Address) {
121 - bytes[i] = (byte) Short.parseShort(net[i], 10); 184 + return new IpAddress(Version.INET, bytes);
122 } 185 }
123 - return new IpAddress(Version.INET, bytes); 186 + if (addr instanceof Inet6Address) {
124 - } 187 + return new IpAddress(Version.INET6, bytes);
125 - 188 + }
126 - /** 189 + final String msg = "Unrecognized IP version address string: " + value;
127 - * Returns the IP version of this address. 190 + throw new IllegalArgumentException(msg);
128 - *
129 - * @return the version
130 - */
131 - public Version version() {
132 - return this.version;
133 - }
134 -
135 - /**
136 - * Returns the IP address as a byte array.
137 - *
138 - * @return a byte array
139 - */
140 - public byte[] toOctets() {
141 - return Arrays.copyOf(this.octets, INET_BYTE_LENGTH);
142 - }
143 -
144 - /**
145 - * Returns the integral value of this IP address.
146 - *
147 - * @return the IP address's value as an integer
148 - */
149 - public int toInt() {
150 - ByteBuffer bb = ByteBuffer.wrap(octets);
151 - return bb.getInt();
152 } 191 }
153 192
154 /** 193 /**
155 * Creates an IP network mask prefix. 194 * Creates an IP network mask prefix.
156 * 195 *
196 + * @param version the IP address version
157 * @param prefixLength the length of the mask prefix. Must be in the 197 * @param prefixLength the length of the mask prefix. Must be in the
158 - * interval [0, 32] for IPv4 198 + * interval [0, 32] for IPv4, or [0, 128] for IPv6
159 * @return a new IP address that contains a mask prefix of the 199 * @return a new IP address that contains a mask prefix of the
160 * specified length 200 * specified length
201 + * @throws IllegalArgumentException if the arguments are invalid
161 */ 202 */
162 - public static IpAddress makeMaskPrefix(int prefixLength) { 203 + public static IpAddress makeMaskPrefix(Version version, int prefixLength) {
204 + int addrByteLength = byteLength(version);
205 + int addrBitLength = addrByteLength * Byte.SIZE;
206 +
163 // Verify the prefix length 207 // Verify the prefix length
164 - if ((prefixLength < 0) || (prefixLength > INET_BIT_LENGTH)) { 208 + if ((prefixLength < 0) || (prefixLength > addrBitLength)) {
165 - final String msg = "Invalid IPv4 prefix length: " + prefixLength + 209 + final String msg = "Invalid IP prefix length: " + prefixLength +
166 - ". Must be in the interval [0, 32]."; 210 + ". Must be in the interval [0, " + addrBitLength + "].";
167 throw new IllegalArgumentException(msg); 211 throw new IllegalArgumentException(msg);
168 } 212 }
169 213
170 - long v = 214 + // Number of bytes and extra bits that should be all 1s
171 - (0xffffffffL << (INET_BIT_LENGTH - prefixLength)) & 0xffffffffL; 215 + int maskBytes = prefixLength / Byte.SIZE;
172 - return IpAddress.valueOf((int) v); 216 + int maskBits = prefixLength % Byte.SIZE;
217 + byte[] mask = new byte[addrByteLength];
218 +
219 + // Set the bytes and extra bits to 1s
220 + for (int i = 0; i < maskBytes; i++) {
221 + mask[i] = (byte) 0xff; // Set mask bytes to 1s
222 + }
223 + for (int i = maskBytes; i < addrByteLength; i++) {
224 + mask[i] = 0; // Set remaining bytes to 0s
225 + }
226 + if (maskBits > 0) {
227 + mask[maskBytes] = (byte) (0xff << (Byte.SIZE - maskBits));
228 + }
229 + return new IpAddress(version, mask);
173 } 230 }
174 231
175 /** 232 /**
...@@ -178,27 +235,38 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -178,27 +235,38 @@ public final class IpAddress implements Comparable<IpAddress> {
178 * 235 *
179 * @param addr the address to mask 236 * @param addr the address to mask
180 * @param prefixLength the length of the mask prefix. Must be in the 237 * @param prefixLength the length of the mask prefix. Must be in the
181 - * interval [0, 32] for IPv4 238 + * interval [0, 32] for IPv4, or [0, 128] for IPv6
182 * @return a new IP address that is masked with a mask prefix of the 239 * @return a new IP address that is masked with a mask prefix of the
183 * specified length 240 * specified length
241 + * @throws IllegalArgumentException if the prefix length is invalid
184 */ 242 */
185 public static IpAddress makeMaskedAddress(final IpAddress addr, 243 public static IpAddress makeMaskedAddress(final IpAddress addr,
186 int prefixLength) { 244 int prefixLength) {
187 - IpAddress mask = IpAddress.makeMaskPrefix(prefixLength); 245 + IpAddress mask = IpAddress.makeMaskPrefix(addr.version(),
188 - byte[] net = new byte[INET_BYTE_LENGTH]; 246 + prefixLength);
247 + byte[] net = new byte[mask.octets.length];
189 248
190 // Mask each byte 249 // Mask each byte
191 - for (int i = 0; i < INET_BYTE_LENGTH; i++) { 250 + for (int i = 0; i < net.length; i++) {
192 net[i] = (byte) (addr.octets[i] & mask.octets[i]); 251 net[i] = (byte) (addr.octets[i] & mask.octets[i]);
193 } 252 }
194 - return IpAddress.valueOf(net); 253 + return IpAddress.valueOf(addr.version(), net);
195 } 254 }
196 255
197 @Override 256 @Override
198 public int compareTo(IpAddress o) { 257 public int compareTo(IpAddress o) {
199 - Long lv = ((long) this.toInt()) & 0xffffffffL; 258 + // Compare first the version
200 - Long rv = ((long) o.toInt()) & 0xffffffffL; 259 + if (this.version != o.version) {
201 - return lv.compareTo(rv); 260 + return this.version.compareTo(o.version);
261 + }
262 +
263 + // Compare the bytes, one-by-one
264 + for (int i = 0; i < this.octets.length; i++) {
265 + if (this.octets[i] != o.octets[i]) {
266 + return UnsignedBytes.compare(this.octets[i], o.octets[i]);
267 + }
268 + }
269 + return 0; // Equal
202 } 270 }
203 271
204 @Override 272 @Override
...@@ -222,18 +290,67 @@ public final class IpAddress implements Comparable<IpAddress> { ...@@ -222,18 +290,67 @@ public final class IpAddress implements Comparable<IpAddress> {
222 @Override 290 @Override
223 /* 291 /*
224 * (non-Javadoc) 292 * (non-Javadoc)
225 - * The format is "x.x.x.x" for IPv4 addresses. 293 + * The string representation of the IP address: "x.x.x.x" for IPv4
294 + * addresses, or ':' separated string for IPv6 addresses.
226 * 295 *
227 * @see java.lang.Object#toString() 296 * @see java.lang.Object#toString()
228 */ 297 */
229 public String toString() { 298 public String toString() {
230 - final StringBuilder builder = new StringBuilder(); 299 + InetAddress inetAddr = null;
231 - for (final byte b : this.octets) { 300 + try {
232 - if (builder.length() > 0) { 301 + inetAddr = InetAddress.getByAddress(octets);
233 - builder.append("."); 302 + } catch (UnknownHostException e) {
303 + // Should never happen
304 + checkState(false, "Internal error: Ip6Address.toString()");
305 + return "[Invalid IP Address]";
306 + }
307 + return InetAddresses.toAddrString(inetAddr);
308 + }
309 +
310 + /**
311 + * Gets the IP address name for the IP address version.
312 + *
313 + * @param version the IP address version
314 + * @return the IP address name for the IP address version
315 + */
316 + private static String addressName(Version version) {
317 + switch (version) {
318 + case INET:
319 + return "IPv4";
320 + case INET6:
321 + return "IPv6";
322 + default:
323 + break;
324 + }
325 + return "UnknownIP(" + version + ")";
326 + }
327 +
328 + /**
329 + * Checks whether the arguments are valid.
330 + *
331 + * @param version the IP address version
332 + * @param value the IP address value stored in a byte array
333 + * @param offset the offset in bytes from the beginning of the byte
334 + * array with the address
335 + * @throws IllegalArgumentException if any of the arguments is invalid
336 + */
337 + private static void checkArguments(Version version, byte[] value,
338 + int offset) {
339 + // Check the offset and byte array length
340 + int addrByteLength = byteLength(version);
341 + if ((offset < 0) || (offset + addrByteLength > value.length)) {
342 + String msg;
343 + if (value.length < addrByteLength) {
344 + msg = "Invalid " + addressName(version) +
345 + " address array: array length: " + value.length +
346 + ". Must be at least " + addrByteLength;
347 + } else {
348 + msg = "Invalid " + addressName(version) +
349 + " address array: array offset: " + offset +
350 + ". Must be in the interval [0, " +
351 + (value.length - addrByteLength) + "]";
234 } 352 }
235 - builder.append(String.format("%d", b & 0xff)); 353 + throw new IllegalArgumentException(msg);
236 } 354 }
237 - return builder.toString();
238 } 355 }
239 } 356 }
......
...@@ -76,12 +76,15 @@ public final class IpPrefix { ...@@ -76,12 +76,15 @@ public final class IpPrefix {
76 /** 76 /**
77 * Converts a byte array and a prefix length into an IP prefix. 77 * Converts a byte array and a prefix length into an IP prefix.
78 * 78 *
79 + * @param version the IP address version
79 * @param address the IP address value stored in network byte order 80 * @param address the IP address value stored in network byte order
80 * @param prefixLength the prefix length 81 * @param prefixLength the prefix length
81 * @return an IP prefix 82 * @return an IP prefix
82 */ 83 */
83 - public static IpPrefix valueOf(byte[] address, int prefixLength) { 84 + public static IpPrefix valueOf(IpAddress.Version version, byte[] address,
84 - return new IpPrefix(IpAddress.valueOf(address), prefixLength); 85 + int prefixLength) {
86 + return new IpPrefix(IpAddress.valueOf(version, address),
87 + prefixLength);
85 } 88 }
86 89
87 /** 90 /**
......
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * 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
7 + *
8 + * 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.
15 + */
16 +package org.onlab.packet;
17 +
18 +import org.junit.Test;
19 +
20 +import static org.hamcrest.Matchers.is;
21 +import static org.hamcrest.Matchers.not;
22 +import static org.junit.Assert.assertThat;
23 +import static org.junit.Assert.assertTrue;
24 +import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
25 +
26 +/**
27 + * Tests for class {@link IpAddress}.
28 + */
29 +public class IpAddressTest {
30 + /**
31 + * Tests the immutability of {@link IpAddress}.
32 + */
33 + @Test
34 + public void testImmutable() {
35 + assertThatClassIsImmutable(IpAddress.class);
36 + }
37 +
38 + /**
39 + * Tests the length of the address in bytes (octets).
40 + */
41 + @Test
42 + public void testAddrByteLength() {
43 + assertThat(IpAddress.INET_BYTE_LENGTH, is(4));
44 + assertThat(IpAddress.INET6_BYTE_LENGTH, is(16));
45 + assertThat(IpAddress.byteLength(IpAddress.Version.INET), is(4));
46 + assertThat(IpAddress.byteLength(IpAddress.Version.INET6), is(16));
47 + }
48 +
49 + /**
50 + * Tests the length of the address in bits.
51 + */
52 + @Test
53 + public void testAddrBitLength() {
54 + assertThat(IpAddress.INET_BIT_LENGTH, is(32));
55 + assertThat(IpAddress.INET6_BIT_LENGTH, is(128));
56 + }
57 +
58 + /**
59 + * Tests returning the IP address version.
60 + */
61 + @Test
62 + public void testVersion() {
63 + IpAddress ipAddress;
64 +
65 + // IPv4
66 + ipAddress = IpAddress.valueOf("0.0.0.0");
67 + assertThat(ipAddress.version(), is(IpAddress.Version.INET));
68 +
69 + // IPv6
70 + ipAddress = IpAddress.valueOf("::");
71 + assertThat(ipAddress.version(), is(IpAddress.Version.INET6));
72 + }
73 +
74 + /**
75 + * Tests returning an IPv4 address as a byte array.
76 + */
77 + @Test
78 + public void testAddressToOctetsIPv4() {
79 + IpAddress ipAddress;
80 +
81 + final byte[] value1 = new byte[] {1, 2, 3, 4};
82 + ipAddress = IpAddress.valueOf("1.2.3.4");
83 + assertThat(ipAddress.toOctets(), is(value1));
84 +
85 + final byte[] value2 = new byte[] {0, 0, 0, 0};
86 + ipAddress = IpAddress.valueOf("0.0.0.0");
87 + assertThat(ipAddress.toOctets(), is(value2));
88 +
89 + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
90 + (byte) 0xff, (byte) 0xff};
91 + ipAddress = IpAddress.valueOf("255.255.255.255");
92 + assertThat(ipAddress.toOctets(), is(value3));
93 + }
94 +
95 + /**
96 + * Tests returning an IPv6 address as a byte array.
97 + */
98 + @Test
99 + public void testAddressToOctetsIPv6() {
100 + IpAddress ipAddress;
101 +
102 + final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22,
103 + 0x33, 0x33, 0x44, 0x44,
104 + 0x55, 0x55, 0x66, 0x66,
105 + 0x77, 0x77,
106 + (byte) 0x88, (byte) 0x88};
107 + ipAddress =
108 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
109 + assertThat(ipAddress.toOctets(), is(value1));
110 +
111 + final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00,
112 + 0x00, 0x00, 0x00, 0x00,
113 + 0x00, 0x00, 0x00, 0x00,
114 + 0x00, 0x00, 0x00, 0x00};
115 + ipAddress = IpAddress.valueOf("::");
116 + assertThat(ipAddress.toOctets(), is(value2));
117 +
118 + final byte[] value3 = new byte[] {(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 + (byte) 0xff, (byte) 0xff};
126 + ipAddress =
127 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
128 + assertThat(ipAddress.toOctets(), is(value3));
129 + }
130 +
131 + /**
132 + * Tests returning an IPv4 address asn an integer.
133 + */
134 + @Test
135 + public void testToint() {
136 + IpAddress ipAddress;
137 +
138 + ipAddress = IpAddress.valueOf("1.2.3.4");
139 + assertThat(ipAddress.toInt(), is(0x01020304));
140 +
141 + ipAddress = IpAddress.valueOf("0.0.0.0");
142 + assertThat(ipAddress.toInt(), is(0));
143 +
144 + ipAddress = IpAddress.valueOf("255.255.255.255");
145 + assertThat(ipAddress.toInt(), is(-1));
146 + }
147 +
148 + /**
149 + * Tests valueOf() converter for an integer value.
150 + */
151 + @Test
152 + public void testValueOfForInteger() {
153 + IpAddress ipAddress;
154 +
155 + ipAddress = IpAddress.valueOf(0x01020304);
156 + assertThat(ipAddress.toString(), is("1.2.3.4"));
157 +
158 + ipAddress = IpAddress.valueOf(0);
159 + assertThat(ipAddress.toString(), is("0.0.0.0"));
160 +
161 + ipAddress = IpAddress.valueOf(0xffffffff);
162 + assertThat(ipAddress.toString(), is("255.255.255.255"));
163 + }
164 +
165 + /**
166 + * Tests valueOf() converter for IPv4 byte array.
167 + */
168 + @Test
169 + public void testValueOfByteArrayIPv4() {
170 + IpAddress ipAddress;
171 +
172 + final byte[] value1 = new byte[] {1, 2, 3, 4};
173 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value1);
174 + assertThat(ipAddress.toString(), is("1.2.3.4"));
175 +
176 + final byte[] value2 = new byte[] {0, 0, 0, 0};
177 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value2);
178 + assertThat(ipAddress.toString(), is("0.0.0.0"));
179 +
180 + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
181 + (byte) 0xff, (byte) 0xff};
182 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value3);
183 + assertThat(ipAddress.toString(), is("255.255.255.255"));
184 + }
185 +
186 + /**
187 + * Tests valueOf() converter for IPv6 byte array.
188 + */
189 + @Test
190 + public void testValueOfByteArrayIPv6() {
191 + IpAddress ipAddress;
192 +
193 + final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22,
194 + 0x33, 0x33, 0x44, 0x44,
195 + 0x55, 0x55, 0x66, 0x66,
196 + 0x77, 0x77,
197 + (byte) 0x88, (byte) 0x88};
198 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value1);
199 + assertThat(ipAddress.toString(),
200 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
201 +
202 + final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00,
203 + 0x00, 0x00, 0x00, 0x00,
204 + 0x00, 0x00, 0x00, 0x00,
205 + 0x00, 0x00, 0x00, 0x00};
206 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value2);
207 + assertThat(ipAddress.toString(), is("::"));
208 +
209 + final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
210 + (byte) 0xff, (byte) 0xff,
211 + (byte) 0xff, (byte) 0xff,
212 + (byte) 0xff, (byte) 0xff,
213 + (byte) 0xff, (byte) 0xff,
214 + (byte) 0xff, (byte) 0xff,
215 + (byte) 0xff, (byte) 0xff,
216 + (byte) 0xff, (byte) 0xff};
217 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value3);
218 + assertThat(ipAddress.toString(),
219 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
220 + }
221 +
222 + /**
223 + * Tests invalid valueOf() converter for a null array for IPv4.
224 + */
225 + @Test(expected = NullPointerException.class)
226 + public void testInvalidValueOfNullArrayIPv4() {
227 + IpAddress ipAddress;
228 +
229 + final byte[] fromArray = null;
230 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, fromArray);
231 + }
232 +
233 + /**
234 + * Tests invalid valueOf() converter for a null array for IPv6.
235 + */
236 + @Test(expected = NullPointerException.class)
237 + public void testInvalidValueOfNullArrayIPv6() {
238 + IpAddress ipAddress;
239 +
240 + final byte[] fromArray = null;
241 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, fromArray);
242 + }
243 +
244 + /**
245 + * Tests invalid valueOf() converger for an array that is too short for
246 + * IPv4.
247 + */
248 + @Test(expected = IllegalArgumentException.class)
249 + public void testInvalidValueOfShortArrayIPv4() {
250 + IpAddress ipAddress;
251 +
252 + final byte[] fromArray = new byte[] {1, 2, 3};
253 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, fromArray);
254 + }
255 +
256 + /**
257 + * Tests invalid valueOf() converger for an array that is too short for
258 + * IPv6.
259 + */
260 + @Test(expected = IllegalArgumentException.class)
261 + public void testInvalidValueOfShortArrayIPv6() {
262 + IpAddress ipAddress;
263 +
264 + final byte[] fromArray = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
265 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, fromArray);
266 + }
267 +
268 + /**
269 + * Tests valueOf() converter for IPv4 byte array and an offset.
270 + */
271 + @Test
272 + public void testValueOfByteArrayOffsetIPv4() {
273 + IpAddress ipAddress;
274 +
275 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
276 + 1, 2, 3, 4,
277 + 44, 55}; // Extra bytes
278 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value1, 3);
279 + assertThat(ipAddress.toString(), is("1.2.3.4"));
280 +
281 + final byte[] value2 = new byte[] {11, 22, // Preamble
282 + 0, 0, 0, 0,
283 + 33}; // Extra bytes
284 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value2, 2);
285 + assertThat(ipAddress.toString(), is("0.0.0.0"));
286 +
287 + final byte[] value3 = new byte[] {11, 22, // Preamble
288 + (byte) 0xff, (byte) 0xff,
289 + (byte) 0xff, (byte) 0xff,
290 + 33}; // Extra bytes
291 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value3, 2);
292 + assertThat(ipAddress.toString(), is("255.255.255.255"));
293 + }
294 +
295 + /**
296 + * Tests valueOf() converter for IPv6 byte array and an offset.
297 + */
298 + @Test
299 + public void testValueOfByteArrayOffsetIPv6() {
300 + IpAddress ipAddress;
301 +
302 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
303 + 0x11, 0x11, 0x22, 0x22,
304 + 0x33, 0x33, 0x44, 0x44,
305 + 0x55, 0x55, 0x66, 0x66,
306 + 0x77, 0x77,
307 + (byte) 0x88, (byte) 0x88,
308 + 44, 55}; // Extra bytes
309 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value1, 3);
310 + assertThat(ipAddress.toString(),
311 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
312 +
313 + final byte[] value2 = new byte[] {11, 22, // Preamble
314 + 0x00, 0x00, 0x00, 0x00,
315 + 0x00, 0x00, 0x00, 0x00,
316 + 0x00, 0x00, 0x00, 0x00,
317 + 0x00, 0x00, 0x00, 0x00,
318 + 33}; // Extra bytes
319 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value2, 2);
320 + assertThat(ipAddress.toString(), is("::"));
321 +
322 + final byte[] value3 = new byte[] {11, 22, // Preamble
323 + (byte) 0xff, (byte) 0xff,
324 + (byte) 0xff, (byte) 0xff,
325 + (byte) 0xff, (byte) 0xff,
326 + (byte) 0xff, (byte) 0xff,
327 + (byte) 0xff, (byte) 0xff,
328 + (byte) 0xff, (byte) 0xff,
329 + (byte) 0xff, (byte) 0xff,
330 + (byte) 0xff, (byte) 0xff,
331 + 33}; // Extra bytes
332 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value3, 2);
333 + assertThat(ipAddress.toString(),
334 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
335 + }
336 +
337 + /**
338 + * Tests invalid valueOf() converger for an array and an invalid offset
339 + * for IPv4.
340 + */
341 + @Test(expected = IllegalArgumentException.class)
342 + public void testInvalidValueOfArrayInvalidOffsetIPv4() {
343 + IpAddress ipAddress;
344 +
345 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
346 + 1, 2, 3, 4,
347 + 44, 55}; // Extra bytes
348 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET, value1, 6);
349 + }
350 +
351 + /**
352 + * Tests invalid valueOf() converger for an array and an invalid offset
353 + * for IPv6.
354 + */
355 + @Test(expected = IllegalArgumentException.class)
356 + public void testInvalidValueOfArrayInvalidOffsetIPv6() {
357 + IpAddress ipAddress;
358 +
359 + final byte[] value1 = new byte[] {11, 22, 33, // Preamble
360 + 0x11, 0x11, 0x22, 0x22,
361 + 0x33, 0x33, 0x44, 0x44,
362 + 0x55, 0x55, 0x66, 0x66,
363 + 0x77, 0x77,
364 + (byte) 0x88, (byte) 0x88,
365 + 44, 55}; // Extra bytes
366 + ipAddress = IpAddress.valueOf(IpAddress.Version.INET6, value1, 6);
367 + }
368 +
369 + /**
370 + * Tests valueOf() converter for IPv4 string.
371 + */
372 + @Test
373 + public void testValueOfStringIPv4() {
374 + IpAddress ipAddress;
375 +
376 + ipAddress = IpAddress.valueOf("1.2.3.4");
377 + assertThat(ipAddress.toString(), is("1.2.3.4"));
378 +
379 + ipAddress = IpAddress.valueOf("0.0.0.0");
380 + assertThat(ipAddress.toString(), is("0.0.0.0"));
381 +
382 + ipAddress = IpAddress.valueOf("255.255.255.255");
383 + assertThat(ipAddress.toString(), is("255.255.255.255"));
384 + }
385 +
386 + /**
387 + * Tests valueOf() converter for IPv6 string.
388 + */
389 + @Test
390 + public void testValueOfStringIPv6() {
391 + IpAddress ipAddress;
392 +
393 + ipAddress =
394 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
395 + assertThat(ipAddress.toString(),
396 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
397 +
398 + ipAddress = IpAddress.valueOf("::");
399 + assertThat(ipAddress.toString(), is("::"));
400 +
401 + ipAddress =
402 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
403 + assertThat(ipAddress.toString(),
404 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
405 + }
406 +
407 + /**
408 + * Tests invalid valueOf() converter for a null string.
409 + */
410 + @Test(expected = NullPointerException.class)
411 + public void testInvalidValueOfNullString() {
412 + IpAddress ipAddress;
413 +
414 + String fromString = null;
415 + ipAddress = IpAddress.valueOf(fromString);
416 + }
417 +
418 + /**
419 + * Tests invalid valueOf() converter for an empty string.
420 + */
421 + @Test(expected = IllegalArgumentException.class)
422 + public void testInvalidValueOfEmptyString() {
423 + IpAddress ipAddress;
424 +
425 + String fromString = "";
426 + ipAddress = IpAddress.valueOf(fromString);
427 + }
428 +
429 + /**
430 + * Tests invalid valueOf() converter for an incorrect string.
431 + */
432 + @Test(expected = IllegalArgumentException.class)
433 + public void testInvalidValueOfIncorrectString() {
434 + IpAddress ipAddress;
435 +
436 + String fromString = "NoSuchIpAddress";
437 + ipAddress = IpAddress.valueOf(fromString);
438 + }
439 +
440 + /**
441 + * Tests making a mask prefix for a given prefix length for IPv4.
442 + */
443 + @Test
444 + public void testMakeMaskPrefixIPv4() {
445 + IpAddress ipAddress;
446 +
447 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 25);
448 + assertThat(ipAddress.toString(), is("255.255.255.128"));
449 +
450 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 0);
451 + assertThat(ipAddress.toString(), is("0.0.0.0"));
452 +
453 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 32);
454 + assertThat(ipAddress.toString(), is("255.255.255.255"));
455 + }
456 +
457 + /**
458 + * Tests making a mask prefix for a given prefix length for IPv6.
459 + */
460 + @Test
461 + public void testMakeMaskPrefixIPv6() {
462 + IpAddress ipAddress;
463 +
464 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 8);
465 + assertThat(ipAddress.toString(), is("ff00::"));
466 +
467 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 120);
468 + assertThat(ipAddress.toString(),
469 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"));
470 +
471 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 0);
472 + assertThat(ipAddress.toString(), is("::"));
473 +
474 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 128);
475 + assertThat(ipAddress.toString(),
476 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
477 +
478 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 64);
479 + assertThat(ipAddress.toString(), is("ffff:ffff:ffff:ffff::"));
480 + }
481 +
482 + /**
483 + * Tests making a mask prefix for an invalid prefix length for IPv4:
484 + * negative prefix length.
485 + */
486 + @Test(expected = IllegalArgumentException.class)
487 + public void testInvalidMakeNegativeMaskPrefixIPv4() {
488 + IpAddress ipAddress;
489 +
490 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, -1);
491 + }
492 +
493 + /**
494 + * Tests making a mask prefix for an invalid prefix length for IPv6:
495 + * negative prefix length.
496 + */
497 + @Test(expected = IllegalArgumentException.class)
498 + public void testInvalidMakeNegativeMaskPrefixIPv6() {
499 + IpAddress ipAddress;
500 +
501 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, -1);
502 + }
503 +
504 + /**
505 + * Tests making a mask prefix for an invalid prefix length for IPv4:
506 + * too long prefix length.
507 + */
508 + @Test(expected = IllegalArgumentException.class)
509 + public void testInvalidMakeTooLongMaskPrefixIPv4() {
510 + IpAddress ipAddress;
511 +
512 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET, 33);
513 + }
514 +
515 + /**
516 + * Tests making a mask prefix for an invalid prefix length for IPv6:
517 + * too long prefix length.
518 + */
519 + @Test(expected = IllegalArgumentException.class)
520 + public void testInvalidMakeTooLongMaskPrefixIPv6() {
521 + IpAddress ipAddress;
522 +
523 + ipAddress = IpAddress.makeMaskPrefix(IpAddress.Version.INET6, 129);
524 + }
525 +
526 + /**
527 + * Tests making of a masked address for IPv4.
528 + */
529 + @Test
530 + public void testMakeMaskedAddressIPv4() {
531 + IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
532 + IpAddress ipAddressMasked;
533 +
534 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 24);
535 + assertThat(ipAddressMasked.toString(), is("1.2.3.0"));
536 +
537 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 0);
538 + assertThat(ipAddressMasked.toString(), is("0.0.0.0"));
539 +
540 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 32);
541 + assertThat(ipAddressMasked.toString(), is("1.2.3.5"));
542 + }
543 +
544 + /**
545 + * Tests making of a masked address for IPv6.
546 + */
547 + @Test
548 + public void testMakeMaskedAddressIPv6() {
549 + IpAddress ipAddress =
550 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
551 + IpAddress ipAddressMasked;
552 +
553 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 8);
554 + assertThat(ipAddressMasked.toString(), is("1100::"));
555 +
556 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 120);
557 + assertThat(ipAddressMasked.toString(),
558 + is("1111:2222:3333:4444:5555:6666:7777:8800"));
559 +
560 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 0);
561 + assertThat(ipAddressMasked.toString(), is("::"));
562 +
563 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 128);
564 + assertThat(ipAddressMasked.toString(),
565 + is("1111:2222:3333:4444:5555:6666:7777:8885"));
566 +
567 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 64);
568 + assertThat(ipAddressMasked.toString(), is("1111:2222:3333:4444::"));
569 + }
570 +
571 + /**
572 + * Tests making of a masked address for invalid prefix length for IPv4:
573 + * negative prefix length.
574 + */
575 + @Test(expected = IllegalArgumentException.class)
576 + public void testInvalidMakeNegativeMaskedAddressIPv4() {
577 + IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
578 + IpAddress ipAddressMasked;
579 +
580 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, -1);
581 + }
582 +
583 + /**
584 + * Tests making of a masked address for invalid prefix length for IPv6:
585 + * negative prefix length.
586 + */
587 + @Test(expected = IllegalArgumentException.class)
588 + public void testInvalidMakeNegativeMaskedAddressIPv6() {
589 + IpAddress ipAddress =
590 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
591 + IpAddress ipAddressMasked;
592 +
593 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, -1);
594 + }
595 +
596 + /**
597 + * Tests making of a masked address for an invalid prefix length for IPv4:
598 + * too long prefix length.
599 + */
600 + @Test(expected = IllegalArgumentException.class)
601 + public void testInvalidMakeTooLongMaskedAddressIPv4() {
602 + IpAddress ipAddress = IpAddress.valueOf("1.2.3.5");
603 + IpAddress ipAddressMasked;
604 +
605 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 33);
606 + }
607 +
608 + /**
609 + * Tests making of a masked address for an invalid prefix length for IPv6:
610 + * too long prefix length.
611 + */
612 + @Test(expected = IllegalArgumentException.class)
613 + public void testInvalidMakeTooLongMaskedAddressIPv6() {
614 + IpAddress ipAddress =
615 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8885");
616 + IpAddress ipAddressMasked;
617 +
618 + ipAddressMasked = IpAddress.makeMaskedAddress(ipAddress, 129);
619 + }
620 +
621 + /**
622 + * Tests comparison of {@link IpAddress} for IPv4.
623 + */
624 + @Test
625 + public void testComparisonIPv4() {
626 + IpAddress addr1, addr2, addr3, addr4;
627 +
628 + addr1 = IpAddress.valueOf("1.2.3.4");
629 + addr2 = IpAddress.valueOf("1.2.3.4");
630 + addr3 = IpAddress.valueOf("1.2.3.3");
631 + addr4 = IpAddress.valueOf("1.2.3.5");
632 + assertTrue(addr1.compareTo(addr2) == 0);
633 + assertTrue(addr1.compareTo(addr3) > 0);
634 + assertTrue(addr1.compareTo(addr4) < 0);
635 +
636 + addr1 = IpAddress.valueOf("255.2.3.4");
637 + addr2 = IpAddress.valueOf("255.2.3.4");
638 + addr3 = IpAddress.valueOf("255.2.3.3");
639 + addr4 = IpAddress.valueOf("255.2.3.5");
640 + assertTrue(addr1.compareTo(addr2) == 0);
641 + assertTrue(addr1.compareTo(addr3) > 0);
642 + assertTrue(addr1.compareTo(addr4) < 0);
643 + }
644 +
645 + /**
646 + * Tests comparison of {@link IpAddress} for IPv6.
647 + */
648 + @Test
649 + public void testComparisonIPv6() {
650 + IpAddress addr1, addr2, addr3, addr4;
651 +
652 + addr1 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
653 + addr2 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
654 + addr3 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8887");
655 + addr4 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8889");
656 + assertTrue(addr1.compareTo(addr2) == 0);
657 + assertTrue(addr1.compareTo(addr3) > 0);
658 + assertTrue(addr1.compareTo(addr4) < 0);
659 +
660 + addr1 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
661 + addr2 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
662 + addr3 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8887");
663 + addr4 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8889");
664 + assertTrue(addr1.compareTo(addr2) == 0);
665 + assertTrue(addr1.compareTo(addr3) > 0);
666 + assertTrue(addr1.compareTo(addr4) < 0);
667 +
668 + addr1 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
669 + addr2 = IpAddress.valueOf("ffff:2222:3333:4444:5555:6666:7777:8888");
670 + addr3 = IpAddress.valueOf("ffff:2222:3333:4443:5555:6666:7777:8888");
671 + addr4 = IpAddress.valueOf("ffff:2222:3333:4445:5555:6666:7777:8888");
672 + assertTrue(addr1.compareTo(addr2) == 0);
673 + assertTrue(addr1.compareTo(addr3) > 0);
674 + assertTrue(addr1.compareTo(addr4) < 0);
675 + }
676 +
677 + /**
678 + * Tests equality of {@link IpAddress} for IPv4.
679 + */
680 + @Test
681 + public void testEqualityIPv4() {
682 + IpAddress addr1, addr2;
683 +
684 + addr1 = IpAddress.valueOf("1.2.3.4");
685 + addr2 = IpAddress.valueOf("1.2.3.4");
686 + assertThat(addr1, is(addr2));
687 +
688 + addr1 = IpAddress.valueOf("0.0.0.0");
689 + addr2 = IpAddress.valueOf("0.0.0.0");
690 + assertThat(addr1, is(addr2));
691 +
692 + addr1 = IpAddress.valueOf("255.255.255.255");
693 + addr2 = IpAddress.valueOf("255.255.255.255");
694 + assertThat(addr1, is(addr2));
695 + }
696 +
697 + /**
698 + * Tests equality of {@link IpAddress} for IPv6.
699 + */
700 + @Test
701 + public void testEqualityIPv6() {
702 + IpAddress addr1, addr2;
703 +
704 + addr1 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
705 + addr2 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
706 + assertThat(addr1, is(addr2));
707 +
708 + addr1 = IpAddress.valueOf("::");
709 + addr2 = IpAddress.valueOf("::");
710 + assertThat(addr1, is(addr2));
711 +
712 + addr1 = IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
713 + addr2 = IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
714 + assertThat(addr1, is(addr2));
715 + }
716 +
717 + /**
718 + * Tests non-equality of {@link IpAddress} for IPv4.
719 + */
720 + @Test
721 + public void testNonEqualityIPv4() {
722 + IpAddress addr1, addr2, addr3, addr4;
723 +
724 + addr1 = IpAddress.valueOf("1.2.3.4");
725 + addr2 = IpAddress.valueOf("1.2.3.5");
726 + addr3 = IpAddress.valueOf("0.0.0.0");
727 + addr4 = IpAddress.valueOf("255.255.255.255");
728 + assertThat(addr1, is(not(addr2)));
729 + assertThat(addr3, is(not(addr2)));
730 + assertThat(addr4, is(not(addr2)));
731 + }
732 +
733 + /**
734 + * Tests non-equality of {@link IpAddress} for IPv6.
735 + */
736 + @Test
737 + public void testNonEqualityIPv6() {
738 + IpAddress addr1, addr2, addr3, addr4;
739 +
740 + addr1 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
741 + addr2 = IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:888A");
742 + addr3 = IpAddress.valueOf("::");
743 + addr4 = IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
744 + assertThat(addr1, is(not(addr2)));
745 + assertThat(addr3, is(not(addr2)));
746 + assertThat(addr4, is(not(addr2)));
747 + }
748 +
749 + /**
750 + * Tests object string representation for IPv4.
751 + */
752 + @Test
753 + public void testToStringIPv4() {
754 + IpAddress ipAddress;
755 +
756 + ipAddress = IpAddress.valueOf("1.2.3.4");
757 + assertThat(ipAddress.toString(), is("1.2.3.4"));
758 +
759 + ipAddress = IpAddress.valueOf("0.0.0.0");
760 + assertThat(ipAddress.toString(), is("0.0.0.0"));
761 +
762 + ipAddress = IpAddress.valueOf("255.255.255.255");
763 + assertThat(ipAddress.toString(), is("255.255.255.255"));
764 + }
765 +
766 + /**
767 + * Tests object string representation for IPv6.
768 + */
769 + @Test
770 + public void testToStringIPv6() {
771 + IpAddress ipAddress;
772 +
773 + ipAddress =
774 + IpAddress.valueOf("1111:2222:3333:4444:5555:6666:7777:8888");
775 + assertThat(ipAddress.toString(),
776 + is("1111:2222:3333:4444:5555:6666:7777:8888"));
777 +
778 + ipAddress = IpAddress.valueOf("1111::8888");
779 + assertThat(ipAddress.toString(), is("1111::8888"));
780 +
781 + ipAddress = IpAddress.valueOf("1111::");
782 + assertThat(ipAddress.toString(), is("1111::"));
783 +
784 + ipAddress = IpAddress.valueOf("::8888");
785 + assertThat(ipAddress.toString(), is("::8888"));
786 +
787 + ipAddress = IpAddress.valueOf("::");
788 + assertThat(ipAddress.toString(), is("::"));
789 +
790 + ipAddress =
791 + IpAddress.valueOf("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
792 + assertThat(ipAddress.toString(),
793 + is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
794 + }
795 +}
...@@ -38,9 +38,11 @@ public class IpPrefixTest { ...@@ -38,9 +38,11 @@ public class IpPrefixTest {
38 38
39 @Test 39 @Test
40 public void testEquality() { 40 public void testEquality() {
41 - IpPrefix ip1 = IpPrefix.valueOf(BYTES1, IpPrefix.MAX_INET_MASK_LENGTH); 41 + IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
42 + BYTES1, IpPrefix.MAX_INET_MASK_LENGTH);
42 IpPrefix ip2 = IpPrefix.valueOf(INTVAL1, IpPrefix.MAX_INET_MASK_LENGTH); 43 IpPrefix ip2 = IpPrefix.valueOf(INTVAL1, IpPrefix.MAX_INET_MASK_LENGTH);
43 - IpPrefix ip3 = IpPrefix.valueOf(BYTES2, IpPrefix.MAX_INET_MASK_LENGTH); 44 + IpPrefix ip3 = IpPrefix.valueOf(IpAddress.Version.INET,
45 + BYTES2, IpPrefix.MAX_INET_MASK_LENGTH);
44 IpPrefix ip4 = IpPrefix.valueOf(INTVAL2, IpPrefix.MAX_INET_MASK_LENGTH); 46 IpPrefix ip4 = IpPrefix.valueOf(INTVAL2, IpPrefix.MAX_INET_MASK_LENGTH);
45 IpPrefix ip5 = IpPrefix.valueOf(STRVAL); 47 IpPrefix ip5 = IpPrefix.valueOf(STRVAL);
46 48
...@@ -50,16 +52,19 @@ public class IpPrefixTest { ...@@ -50,16 +52,19 @@ public class IpPrefixTest {
50 .testEquals(); 52 .testEquals();
51 53
52 // string conversions 54 // string conversions
53 - IpPrefix ip6 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); 55 + IpPrefix ip6 = IpPrefix.valueOf(IpAddress.Version.INET,
56 + BYTES1, MASK_LENGTH);
54 IpPrefix ip7 = IpPrefix.valueOf("10.0.0.10/16"); 57 IpPrefix ip7 = IpPrefix.valueOf("10.0.0.10/16");
55 - IpPrefix ip8 = IpPrefix.valueOf(new byte [] {0xa, 0x0, 0x0, 0xc}, 16); 58 + IpPrefix ip8 = IpPrefix.valueOf(IpAddress.Version.INET,
59 + new byte [] {0xa, 0x0, 0x0, 0xc}, 16);
56 assertEquals("incorrect address conversion", ip6, ip7); 60 assertEquals("incorrect address conversion", ip6, ip7);
57 assertEquals("incorrect address conversion", ip5, ip8); 61 assertEquals("incorrect address conversion", ip5, ip8);
58 } 62 }
59 63
60 @Test 64 @Test
61 public void basics() { 65 public void basics() {
62 - IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); 66 + IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
67 + BYTES1, MASK_LENGTH);
63 final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0x0}; 68 final byte [] bytes = new byte [] {0xa, 0x0, 0x0, 0x0};
64 69
65 // check fields 70 // check fields
...@@ -74,7 +79,8 @@ public class IpPrefixTest { ...@@ -74,7 +79,8 @@ public class IpPrefixTest {
74 @Test 79 @Test
75 public void netmasks() { 80 public void netmasks() {
76 // masked 81 // masked
77 - IpPrefix ip1 = IpPrefix.valueOf(BYTES1, MASK_LENGTH); 82 + IpPrefix ip1 = IpPrefix.valueOf(IpAddress.Version.INET,
83 + BYTES1, MASK_LENGTH);
78 IpPrefix ip2 = IpPrefix.valueOf("10.0.0.10/16"); 84 IpPrefix ip2 = IpPrefix.valueOf("10.0.0.10/16");
79 IpPrefix ip3 = IpPrefix.valueOf("10.0.0.0/16"); 85 IpPrefix ip3 = IpPrefix.valueOf("10.0.0.0/16");
80 assertEquals("incorrect binary masked address", 86 assertEquals("incorrect binary masked address",
...@@ -87,9 +93,12 @@ public class IpPrefixTest { ...@@ -87,9 +93,12 @@ public class IpPrefixTest {
87 93
88 @Test 94 @Test
89 public void testContainsIpPrefix() { 95 public void testContainsIpPrefix() {
90 - IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31); 96 + IpPrefix slash31 = IpPrefix.valueOf(IpAddress.Version.INET,
91 - IpPrefix slash32 = IpPrefix.valueOf(BYTES1, 32); 97 + BYTES1, 31);
92 - IpPrefix differentSlash32 = IpPrefix.valueOf(BYTES2, 32); 98 + IpPrefix slash32 = IpPrefix.valueOf(IpAddress.Version.INET,
99 + BYTES1, 32);
100 + IpPrefix differentSlash32 = IpPrefix.valueOf(IpAddress.Version.INET,
101 + BYTES2, 32);
93 102
94 assertTrue(slash31.contains(differentSlash32)); 103 assertTrue(slash31.contains(differentSlash32));
95 assertFalse(differentSlash32.contains(slash31)); 104 assertFalse(differentSlash32.contains(slash31));
...@@ -109,8 +118,9 @@ public class IpPrefixTest { ...@@ -109,8 +118,9 @@ public class IpPrefixTest {
109 118
110 @Test 119 @Test
111 public void testContainsIpAddress() { 120 public void testContainsIpAddress() {
112 - IpPrefix slash31 = IpPrefix.valueOf(BYTES1, 31); 121 + IpPrefix slash31 = IpPrefix.valueOf(IpAddress.Version.INET,
113 - IpAddress addr32 = IpAddress.valueOf(BYTES1); 122 + BYTES1, 31);
123 + IpAddress addr32 = IpAddress.valueOf(IpAddress.Version.INET, BYTES1);
114 124
115 assertTrue(slash31.contains(addr32)); 125 assertTrue(slash31.contains(addr32));
116 126
......