2 * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.annotations.Beta;
14 import com.google.common.net.InetAddresses;
15 import java.net.Inet4Address;
16 import java.net.Inet6Address;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.util.AbstractMap.SimpleImmutableEntry;
20 import java.util.Map.Entry;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.opendaylight.mdsal.binding.spec.reflect.StringValueObjectFactory;
23 import org.opendaylight.mdsal.model.ietf.util.Ipv4Utils;
24 import org.opendaylight.mdsal.model.ietf.util.Ipv6Utils;
27 * A set of utility methods to efficiently instantiate various ietf-inet-types DTOs.
30 @SuppressWarnings("checkstyle:classTypeParameterName")
31 public abstract class AbstractIetfInetUtil {
32 private static final StringValueObjectFactory<Ipv4AddressNoZone> V4NZ_FACTORY =
33 StringValueObjectFactory.create(Ipv4AddressNoZone.class, "0.0.0.0");
34 private static final StringValueObjectFactory<Ipv4Prefix> P4_FACTORY =
35 StringValueObjectFactory.create(Ipv4Prefix.class, "0.0.0.0/0");
36 private static final StringValueObjectFactory<Ipv6AddressNoZone> V6NZ_FACTORY =
37 StringValueObjectFactory.create(Ipv6AddressNoZone.class, "::0");
38 private static final StringValueObjectFactory<Ipv6Prefix> P6_FACTORY =
39 StringValueObjectFactory.create(Ipv6Prefix.class, "::0/0");
42 * Create an IpAddress by interpreting input bytes as an IPv4 or IPv6 address, based on array length.
44 * @param bytes 4-byte (IPv4) or 6-byte (IPv6) array
45 * @return An IpAddress object
46 * @throws IllegalArgumentException if bytes has length different from 4 or 6
47 * @throws NullPointerException if bytes is null
49 public final @NonNull IpAddress ipAddressFor(final byte @NonNull[] bytes) {
50 return switch (bytes.length) {
51 case Ipv4Utils.INET4_LENGTH -> new IpAddress(ipv4AddressFor(bytes));
52 case Ipv6Utils.INET6_LENGTH -> new IpAddress(ipv6AddressFor(bytes));
53 default -> throwInvalidArray(bytes);
57 public final @NonNull IpAddress ipAddressFor(final @NonNull InetAddress addr) {
59 if (addr instanceof Inet4Address) {
60 return new IpAddress(ipv4AddressFor(addr));
61 } else if (addr instanceof Inet6Address) {
62 return new IpAddress(ipv6AddressFor(addr));
64 throw unhandledAddress(addr);
68 private static <T> @NonNull T requireAddress(final T addr) {
69 return requireNonNull(addr, "Address must not be null");
73 * Create an IpAddress by interpreting input bytes as an IPv4 or IPv6 address, based on array length.
75 * @param bytes 4-byte (IPv4) or 6-byte (IPv6) array
76 * @return A no-zone IpAddress object
77 * @throws IllegalArgumentException if bytes has length different from 4 or 6
78 * @throws NullPointerException if bytes is null
80 public final @NonNull IpAddressNoZone ipAddressNoZoneFor(final byte @NonNull[] bytes) {
81 return switch (bytes.length) {
82 case Ipv4Utils.INET4_LENGTH -> new IpAddressNoZone(ipv4AddressFor(bytes));
83 case Ipv6Utils.INET6_LENGTH -> new IpAddressNoZone(ipv6AddressFor(bytes));
84 default -> throwInvalidArray(bytes);
88 public final @NonNull IpAddressNoZone ipAddressNoZoneFor(final @NonNull InetAddress addr) {
90 if (addr instanceof Inet4Address) {
91 return new IpAddressNoZone(ipv4AddressFor(addr));
92 } else if (addr instanceof Inet6Address) {
93 return new IpAddressNoZone(ipv6AddressFor(addr));
95 throw unhandledAddress(addr);
99 private static <T> T throwInvalidArray(final byte[] bytes) {
100 throw new IllegalArgumentException("Invalid array length " + bytes.length);
103 private static IllegalArgumentException unhandledAddress(final InetAddress addr) {
104 return new IllegalArgumentException("Unhandled address " + addr);
108 * Create an IpPrefix by combining the address with a mask. The address
109 * bytes are interpreted as an address and the specified mask is concatenated to
110 * it. The address bytes are not masked.
112 * @param bytes Input address as a 4-byte (IPv4) or 16-byte (IPv6) array
113 * @param mask Prefix mask
114 * @return An IpPrefix object
115 * @throws IllegalArgumentException if bytes has length different from 4 or 16 or if mask is not
116 * in range 0-32 or 0-128 respectively
117 * @throws NullPointerException if bytes is null
119 public final @NonNull IpPrefix ipPrefixFor(final byte @NonNull[] bytes, final int mask) {
120 return switch (bytes.length) {
121 case Ipv4Utils.INET4_LENGTH -> new IpPrefix(ipv4PrefixFor(bytes, mask));
122 case Ipv6Utils.INET6_LENGTH -> new IpPrefix(ipv6PrefixFor(bytes, mask));
123 default -> throwInvalidArray(bytes);
127 public final @NonNull IpPrefix ipPrefixFor(final @NonNull InetAddress addr, final int mask) {
128 requireAddress(addr);
129 if (addr instanceof Inet4Address) {
130 return new IpPrefix(ipv4PrefixFor(addr, mask));
131 } else if (addr instanceof Inet6Address) {
132 return new IpPrefix(ipv6PrefixFor(addr, mask));
134 throw unhandledAddress(addr);
138 public final @NonNull IpPrefix ipPrefixFor(final @NonNull IpAddress addr) {
139 final var v4 = addr.getIpv4Address();
140 return v4 != null ? new IpPrefix(ipv4PrefixFor(v4)) : new IpPrefix(ipv6PrefixFor(coerceIpv6Address(addr)));
143 public final @NonNull IpPrefix ipPrefixForNoZone(final @NonNull IpAddressNoZone addr) {
144 final var v4 = addr.getIpv4AddressNoZone();
145 return v4 != null ? new IpPrefix(ipv4PrefixFor(inet4AddressForNoZone(v4)))
146 : new IpPrefix(ipv6PrefixFor(coerceIpv6AddressNoZone(addr)));
149 public final @NonNull InetAddress inetAddressFor(final @NonNull IpAddress addr) {
150 final var v4 = addr.getIpv4Address();
151 return v4 != null ? inet4AddressFor(v4) : inet6AddressFor(coerceIpv6Address(addr));
154 public final @NonNull InetAddress inetAddressForNoZone(final @NonNull IpAddressNoZone addr) {
155 final var v4 = addr.getIpv4AddressNoZone();
156 return v4 != null ? inet4AddressForNoZone(v4) : inet6AddressForNoZone(coerceIpv6AddressNoZone(addr));
159 public final @NonNull Inet4Address inet4AddressFor(final @NonNull Ipv4Address addr) {
161 return (Inet4Address) InetAddress.getByAddress(ipv4AddressBytes(addr));
162 } catch (UnknownHostException e) {
163 throw new IllegalArgumentException("Invalid address " + addr, e);
167 public final @NonNull Inet4Address inet4AddressForNoZone(final @NonNull Ipv4AddressNoZone addr) {
169 return (Inet4Address) InetAddress.getByAddress(ipv4AddressNoZoneBytes(addr));
170 } catch (UnknownHostException e) {
171 throw new IllegalArgumentException("Invalid address " + addr, e);
175 public final @NonNull Inet6Address inet6AddressFor(final @NonNull Ipv6Address addr) {
177 return (Inet6Address) InetAddress.getByAddress(ipv6AddressBytes(addr));
178 } catch (UnknownHostException e) {
179 throw new IllegalArgumentException("Invalid address " + addr, e);
183 public final @NonNull Inet6Address inet6AddressForNoZone(final @NonNull Ipv6AddressNoZone addr) {
185 return (Inet6Address) InetAddress.getByAddress(ipv6AddressNoZoneBytes(addr));
186 } catch (UnknownHostException e) {
187 throw new IllegalArgumentException("Invalid address " + addr, e);
192 * Create an Ipv4AddressNoZone by interpreting input bytes as an IPv4 address.
194 * @param bytes 4-byte array
195 * @return An Ipv4AddressNoZone object
196 * @throws IllegalArgumentException if bytes has length different from 4
197 * @throws NullPointerException if bytes is null
199 public final @NonNull Ipv4AddressNoZone ipv4AddressFor(final byte @NonNull[] bytes) {
200 return V4NZ_FACTORY.newInstance(Ipv4Utils.addressString(bytes));
204 * Create an Ipv4AddressNoZone by interpreting an {@link Inet4Address}.
206 * @param addr An {@link Inet4Address}
207 * @return An Ipv4AddressNoZone object
208 * @throws IllegalArgumentException if addr is not an {@link Inet4Address}
209 * @throws NullPointerException if addr is null
211 public final @NonNull Ipv4AddressNoZone ipv4AddressFor(final @NonNull InetAddress addr) {
212 return V4NZ_FACTORY.newInstance(addressStringV4(addr));
216 * Create an Ipv4AddressNoZone by interpreting input 32 bits as an IPv4 address in big-endian format.
218 * @param bits 32 bits, big endian
219 * @return An Ipv4AddressNoZone object
221 public final @NonNull Ipv4AddressNoZone ipv4AddressFor(final int bits) {
222 return V4NZ_FACTORY.newInstance(Ipv4Utils.addressString(bits));
226 * Create an Ipv4AddressNoZone by interpreting an Ipv4Address.
228 * @param addr An Ipv4Address
229 * @return An Ipv4AddressNoZone object
230 * @throws NullPointerException if addr is null
232 public final @NonNull Ipv4AddressNoZone ipv4AddressNoZoneFor(final @NonNull Ipv4Address addr) {
233 requireAddress(addr);
234 return addr instanceof Ipv4AddressNoZone noZone ? noZone
235 : V4NZ_FACTORY.newInstance(stripZone(addr.getValue()));
238 public final @NonNull Ipv4AddressNoZone ipv4AddressFrom(final @NonNull Ipv4Prefix prefix) {
239 return prefixToAddress(V4NZ_FACTORY, prefix.getValue());
242 public final byte @NonNull[] ipv4AddressBytes(final @NonNull Ipv4Address addr) {
244 * This implementation relies heavily on the input string having been validated to comply with
245 * the Ipv4Address pattern, which may include a zone index.
247 final var str = addr.getValue();
248 final int percent = str.indexOf('%');
249 return Ipv4Utils.addressBytes(str, percent == -1 ? str.length() : percent);
252 public final int ipv4AddressBits(final @NonNull Ipv4Address addr) {
253 final var str = addr.getValue();
254 final int percent = str.indexOf('%');
255 return Ipv4Utils.addressBits(str, percent == -1 ? str.length() : percent);
258 public final byte @NonNull[] ipv4AddressNoZoneBytes(final @NonNull Ipv4AddressNoZone addr) {
260 * This implementation relies heavily on the input string having been validated to comply with
261 * the Ipv4AddressNoZone pattern, which must not include a zone index.
263 final String str = addr.getValue();
264 return Ipv4Utils.addressBytes(str, str.length());
267 public final int ipv4AddressNoZoneBits(final @NonNull Ipv4AddressNoZone addr) {
268 final var str = addr.getValue();
269 return Ipv4Utils.addressBits(str, str.length());
273 * Create a /32 Ipv4Prefix by interpreting input bytes as an IPv4 address.
275 * @param bytes four-byte array
276 * @return An Ipv4Prefix object
277 * @throws IllegalArgumentException if bytes has length different from 4
278 * @throws NullPointerException if bytes is null
280 public final @NonNull Ipv4Prefix ipv4PrefixFor(final byte @NonNull[] bytes) {
281 return P4_FACTORY.newInstance(prefixStringV4(bytes));
285 * Create a Ipv4Prefix by combining the address with a mask. The address
286 * bytes are interpreted as an address and the specified mask is concatenated to
287 * it. The address bytes are not masked, hence input <code>address = { 1, 2, 3, 4 }</code>
288 * and <code>mask=24</code> will result in <code>1.2.3.4/24</code>.
290 * @param address Input address as a 4-byte array
291 * @param mask Prefix mask
292 * @return An Ipv4Prefix object
293 * @throws IllegalArgumentException if bytes has length different from 4 or if mask is not in range 0-32
294 * @throws NullPointerException if bytes is null
296 public final @NonNull Ipv4Prefix ipv4PrefixFor(final byte @NonNull[] address, final int mask) {
297 return P4_FACTORY.newInstance(prefixStringV4(address, mask));
301 * Create a /32 Ipv4Prefix for an {@link Inet4Address}.
303 * @param addr An {@link Inet4Address}
304 * @return An Ipv4Prefix object
305 * @throws IllegalArgumentException if addr is not an Inet4Address
306 * @throws NullPointerException if addr is null
308 public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull InetAddress addr) {
309 return P4_FACTORY.newInstance(addressStringV4(addr) + "/32");
313 * Create a Ipv4Prefix by combining the address with a mask. The address bytes are not masked.
315 * @param addr An {@link Inet4Address}
316 * @param mask Prefix mask
317 * @return An Ipv4Prefix object
318 * @throws IllegalArgumentException if addr is not an Inet4Address or if mask is not in range 0-32
319 * @throws NullPointerException if addr is null
321 public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull InetAddress addr, final int mask) {
322 return newIpv4Prefix(addressStringV4(addr), mask);
325 public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull Ipv4Address addr) {
326 return P4_FACTORY.newInstance(stripZone(addr.getValue()) + "/32");
329 public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull Ipv4Address addr, final int mask) {
330 return newIpv4Prefix(stripZone(addr.getValue()), mask);
333 public final @NonNull Ipv4Prefix ipv4PrefixForNoZone(final @NonNull Ipv4AddressNoZone addr) {
334 return P4_FACTORY.newInstance(addr.getValue() + "/32");
337 public final @NonNull Ipv4Prefix ipv4PrefixForNoZone(final @NonNull Ipv4AddressNoZone addr, final int mask) {
338 return newIpv4Prefix(addr.getValue(), mask);
341 public final @NonNull Ipv4Prefix ipv4PrefixForShort(final byte @NonNull[] address, final int mask) {
343 // Easy case, reuse the template
344 return P4_FACTORY.getTemplate();
347 return v4PrefixForShort(address, 0, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask);
350 public final @NonNull Ipv4Prefix ipv4PrefixForShort(final byte @NonNull[] array, final int startOffset,
353 // Easy case, reuse the template
354 return P4_FACTORY.getTemplate();
357 return v4PrefixForShort(array, startOffset, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask);
360 private static String stripZone(final String str) {
361 final int percent = str.indexOf('%');
362 return percent == -1 ? str : str.substring(0, percent);
365 private @NonNull Ipv4Prefix newIpv4Prefix(final String addr, final int mask) {
366 checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask);
367 return P4_FACTORY.newInstance(addr + '/' + mask);
370 public final @NonNull Entry<Ipv4AddressNoZone, Integer> splitIpv4Prefix(final @NonNull Ipv4Prefix prefix) {
371 return splitPrefix(V4NZ_FACTORY, prefix.getValue());
374 public final byte @NonNull[] ipv4PrefixToBytes(final @NonNull Ipv4Prefix prefix) {
375 final var str = prefix.getValue();
376 final int slash = str.lastIndexOf('/');
378 final byte[] bytes = new byte[Ipv4Utils.INET4_LENGTH + 1];
379 Ipv4Utils.fillIpv4Bytes(bytes, 0, str, 0, slash);
380 bytes[Ipv4Utils.INET4_LENGTH] = (byte)Integer.parseInt(str.substring(slash + 1), 10);
385 * Create an Ipv6Address by interpreting input bytes as an IPv6 address.
387 * @param bytes 16-byte array
388 * @return An Ipv6Address object
389 * @throws IllegalArgumentException if bytes has length different from 16
390 * @throws NullPointerException if bytes is null
392 public final @NonNull Ipv6AddressNoZone ipv6AddressFor(final byte @NonNull[] bytes) {
393 return V6NZ_FACTORY.newInstance(addressStringV6(bytes));
397 * Create an Ipv6Address by interpreting an {@link Inet6Address}.
399 * @param addr An {@link Inet6Address}
400 * @return An Ipv6Address object
401 * @throws IllegalArgumentException if addr is not an {@link Inet6Address}
402 * @throws NullPointerException if addr is null
404 public final @NonNull Ipv6AddressNoZone ipv6AddressFor(final @NonNull InetAddress addr) {
405 return V6NZ_FACTORY.newInstance(addressStringV6(addr));
409 * Create an Ipv6AddressNoZone by interpreting an Ipv6Address.
411 * @param addr An Ipv6Address
412 * @return An Ipv6AddressNoZone object
413 * @throws NullPointerException if addr is null
415 public final @NonNull Ipv6AddressNoZone ipv6AddressNoZoneFor(final @NonNull Ipv6Address addr) {
416 requireAddress(addr);
417 return addr instanceof Ipv6AddressNoZone noZone ? noZone
418 : V6NZ_FACTORY.newInstance(stripZone(addr.getValue()));
421 public final @NonNull Ipv6AddressNoZone ipv6AddressFrom(final @NonNull Ipv6Prefix prefix) {
422 return prefixToAddress(V6NZ_FACTORY, prefix.getValue());
425 public final byte @NonNull[] ipv6AddressBytes(final @NonNull Ipv6Address addr) {
426 final var str = addr.getValue();
427 final int percent = str.indexOf('%');
428 return ipv6StringBytes(str, percent == -1 ? str.length() : percent);
431 public final byte @NonNull[] ipv6AddressNoZoneBytes(final @NonNull Ipv6Address addr) {
432 final var str = addr.getValue();
433 return ipv6StringBytes(str, str.length());
436 private static byte @NonNull[] ipv6StringBytes(final @NonNull String str, final int limit) {
437 final byte[] bytes = new byte[Ipv6Utils.INET6_LENGTH];
438 Ipv6Utils.fillIpv6Bytes(bytes, str, limit);
443 * Create a /128 Ipv6Prefix by interpreting input bytes as an IPv6 address.
445 * @param bytes four-byte array
446 * @return An Ipv6Prefix object
447 * @throws IllegalArgumentException if bytes has length different from 16
448 * @throws NullPointerException if bytes is null
450 public final @NonNull Ipv6Prefix ipv6PrefixFor(final byte @NonNull[] bytes) {
451 return P6_FACTORY.newInstance(addressStringV6(bytes) + "/128");
455 * Create a Ipv6Prefix by combining the address with a mask. The address
456 * bytes are interpreted as an address and the specified mask is concatenated to
457 * it. The address bytes are not masked.
459 * @param address Input address as a 16-byte array
460 * @param mask Prefix mask
461 * @return An Ipv6Prefix object
462 * @throws IllegalArgumentException if bytes has length different from 16 or if mask is not in range 0-128
463 * @throws NullPointerException if bytes is null
465 public final @NonNull Ipv6Prefix ipv6PrefixFor(final byte @NonNull[] address, final int mask) {
466 checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask);
467 return P6_FACTORY.newInstance(addressStringV6(address) + '/' + mask);
471 * Create a /128 Ipv6Prefix by interpreting input bytes as an IPv6 address.
473 * @param addr an {@link Inet6Address}
474 * @return An Ipv6Prefix object
475 * @throws IllegalArgumentException if addr is not an Inet6Address
476 * @throws NullPointerException if addr is null
478 public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull InetAddress addr) {
479 return P6_FACTORY.newInstance(addressStringV6(addr) + "/128");
483 * Create a Ipv6Prefix by combining the address with a mask. The address
484 * bytes are interpreted as an address and the specified mask is concatenated to
485 * it. The address bytes are not masked.
487 * @param addr Input address
488 * @param mask Prefix mask
489 * @return An Ipv6Prefix object
490 * @throws IllegalArgumentException if addr is not an Inet6Address or if mask is not in range 0-128
491 * @throws NullPointerException if addr is null
493 public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull InetAddress addr, final int mask) {
494 checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask);
495 return P6_FACTORY.newInstance(addressStringV6(addr) + '/' + mask);
498 public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull Ipv6Address addr) {
499 return P6_FACTORY.newInstance(stripZone(addr.getValue()) + "/128");
502 public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull Ipv6Address addr, final int mask) {
503 return newIpv6Prefix(stripZone(addr.getValue()), mask);
506 public final @NonNull Ipv6Prefix ipv6PrefixForNoZone(final @NonNull Ipv6AddressNoZone addr) {
507 return P6_FACTORY.newInstance(addr.getValue() + "/128");
510 public final @NonNull Ipv6Prefix ipv6PrefixForNoZone(final @NonNull Ipv6AddressNoZone addr, final int mask) {
511 return newIpv6Prefix(addr.getValue(), mask);
514 public final @NonNull Ipv6Prefix ipv6PrefixForShort(final byte @NonNull[] address, final int mask) {
515 return ipv6PrefixForShort(address, 0, mask);
518 public final @NonNull Ipv6Prefix ipv6PrefixForShort(final byte @NonNull[] array, final int startOffset,
521 // Easy case, reuse the template
522 return P6_FACTORY.getTemplate();
525 checkArgument(mask > 0 && mask <= 128, "Invalid mask %s", mask);
526 final int size = mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1);
528 // Until we can instantiate an IPv6 address for a partial array, use a temporary buffer
529 byte[] tmp = new byte[Ipv6Utils.INET6_LENGTH];
530 System.arraycopy(array, startOffset, tmp, 0, size);
531 return ipv6PrefixFor(tmp, mask);
534 private Ipv6Prefix newIpv6Prefix(final String addr, final int mask) {
535 checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask);
536 return P6_FACTORY.newInstance(addr + '/' + mask);
539 public final @NonNull Entry<Ipv6AddressNoZone, Integer> splitIpv6Prefix(final @NonNull Ipv6Prefix prefix) {
540 return splitPrefix(V6NZ_FACTORY, prefix.getValue());
543 private static <T> @NonNull T prefixToAddress(final StringValueObjectFactory<T> factory, final String str) {
544 return factory.newInstance(str.substring(0, str.lastIndexOf('/')));
547 private static <T> @NonNull Entry<T, Integer> splitPrefix(final StringValueObjectFactory<T> factory,
549 final int slash = str.lastIndexOf('/');
550 return new SimpleImmutableEntry<>(factory.newInstance(str.substring(0, slash)),
551 Integer.valueOf(str.substring(slash + 1)));
554 public final byte @NonNull[] ipv6PrefixToBytes(final @NonNull Ipv6Prefix prefix) {
555 final var str = prefix.getValue();
556 final byte[] bytes = new byte[Ipv6Utils.INET6_LENGTH + 1];
557 final int slash = str.lastIndexOf('/');
558 Ipv6Utils.fillIpv6Bytes(bytes, str, slash);
559 bytes[Ipv6Utils.INET6_LENGTH] = (byte)Integer.parseInt(str.substring(slash + 1), 10);
563 private static @NonNull String addressStringV4(final InetAddress addr) {
564 requireAddress(addr);
565 checkArgument(addr instanceof Inet4Address, "Address has to be an Inet4Address");
566 return addr.getHostAddress();
569 private static String addressStringV6(final byte @NonNull[] bytes) {
570 checkArgument(bytes.length == Ipv6Utils.INET6_LENGTH, "IPv6 address length is 16 bytes");
573 return addressStringV6(Inet6Address.getByAddress(null, bytes, null));
574 } catch (UnknownHostException e) {
575 throw new IllegalArgumentException(String.format("Invalid input %s", bytes), e);
579 private static String addressStringV6(final InetAddress addr) {
580 requireAddress(addr);
581 checkArgument(addr instanceof Inet6Address, "Address has to be an Inet6Address");
582 return addressStringV6((Inet6Address) addr);
585 private static String addressStringV6(final Inet6Address addr) {
586 return InetAddresses.toAddrString(addr);
589 private static String prefixStringV4(final byte @NonNull[] bytes) {
590 final StringBuilder sb = new StringBuilder(18);
591 Ipv4Utils.appendIpv4String(sb, bytes);
592 return sb.append("/32").toString();
595 private static String prefixStringV4(final byte @NonNull[] bytes, final int mask) {
596 checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask);
598 final StringBuilder sb = new StringBuilder(18);
599 Ipv4Utils.appendIpv4String(sb, bytes);
600 return sb.append('/').append(mask).toString();
603 private @NonNull Ipv4Prefix v4PrefixForShort(final byte @NonNull[] array, final int startOffset, final int size,
605 if (startOffset == 0 && size == Ipv4Utils.INET4_LENGTH && array.length == Ipv4Utils.INET4_LENGTH) {
606 // Easy case, fall back to non-short
607 return ipv4PrefixFor(array, mask);
610 final StringBuilder sb = new StringBuilder(18);
613 sb.append(Byte.toUnsignedInt(array[startOffset]));
614 for (int i = 1; i < size; i++) {
615 sb.append('.').append(Byte.toUnsignedInt(array[startOffset + i]));
619 for (int i = size; i < Ipv4Utils.INET4_LENGTH; i++) {
624 checkArgument(mask > 0 && mask <= 32, "Invalid mask %s", mask);
625 sb.append('/').append(mask);
627 return P4_FACTORY.newInstance(sb.toString());
630 private static @NonNull Ipv6Address coerceIpv6Address(final @NonNull IpAddress addr) {
631 final var ret = addr.getIpv6Address();
632 checkArgument(ret != null, "Address %s is neither IPv4 nor IPv6", addr);
636 private static @NonNull Ipv6AddressNoZone coerceIpv6AddressNoZone(final @NonNull IpAddressNoZone addr) {
637 final var ret = addr.getIpv6AddressNoZone();
638 checkArgument(ret != null, "Address %s is neither IPv4 nor IPv6", addr);