2 * Copyright (c) 2016 Cisco Systems, Inc. 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.openflowplugin.openflow.md.core.sal.convertor.common;
10 import com.google.common.base.Preconditions;
11 import com.google.common.base.Splitter;
12 import com.google.common.base.Strings;
13 import com.google.common.net.InetAddresses;
14 import com.google.common.primitives.UnsignedBytes;
15 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
16 import java.math.BigInteger;
17 import java.net.Inet4Address;
18 import java.net.InetAddress;
19 import java.net.UnknownHostException;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.BitSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.regex.Pattern;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 public final class IpConversionUtil {
39 private static final Logger LOG = LoggerFactory.getLogger(IpConversionUtil.class);
40 public static final String PREFIX_SEPARATOR = "/";
41 public static final Splitter PREFIX_SPLITTER = Splitter.on('/');
42 private static final Splitter PREFIX_TRIM_SPLITTER = PREFIX_SPLITTER.trimResults().omitEmptyStrings();
43 private static final Splitter PERCENT_SPLITTER = Splitter.on('%').trimResults().omitEmptyStrings();
44 private static final Pattern BITMASK_SPLIT_PATTERN = Pattern.compile("(?!^)");
45 private static final int INADDR4SZ = 4;
46 private static final int INADDR6SZ = 16;
47 private static final int INT16SZ = 2;
48 private static final int IPV4_ADDRESS_LENGTH = 32;
49 private static final int IPV6_ADDRESS_LENGTH = 128;
50 private static final Ipv6ArbitraryMask DEFAULT_IPV6_ARBITRARY_BITMASK =
51 new Ipv6ArbitraryMask("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
54 * Prefix bytearray lookup table. We concatenate the prefixes
55 * to a single byte array and perform offset lookups to ensure
56 * the table is contiguous and save some space.
58 private static final byte[] PREFIX_BYTEARRAYS;
61 final byte[] a = new byte[(INADDR6SZ * Byte.SIZE + 1) * INADDR6SZ];
64 for (int p = 0; p <= INADDR6SZ * Byte.SIZE; ++p) {
66 for (int i = 0; i < INADDR6SZ; ++i) {
67 a[offset++] = (byte) nextNibble(prefix);
72 PREFIX_BYTEARRAYS = a;
75 private static final DottedQuad[] IPV4_BITMASKS;
78 final DottedQuad[] quads = new DottedQuad[IPV4_ADDRESS_LENGTH + 1];
80 for (int i = 0; i <= IPV4_ADDRESS_LENGTH; ++i) {
81 final int maskBits = maskForIpv4Prefix(i);
82 quads[i] = new DottedQuad(new StringBuilder(15)
83 .append(maskBits >>> 24).append('.')
84 .append(maskBits >>> 16 & 0xff).append('.')
85 .append(maskBits >>> 8 & 0xff).append('.')
86 .append(maskBits & 0xff).toString());
89 IPV4_BITMASKS = quads;
93 private IpConversionUtil() {
97 public static Iterator<String> splitToParts(final Ipv4Prefix ipv4Prefix) {
98 return PREFIX_SPLITTER.split(ipv4Prefix.getValue()).iterator();
101 public static Iterator<String> splitToParts(final Ipv6Prefix ipv6Prefix) {
102 return PREFIX_SPLITTER.split(ipv6Prefix.getValue()).iterator();
105 /* This forest of functions has a purpose:
107 * 1. There are multiple coding styles around the plugin, this is necessary in order to have
108 * one mechanism to convert them all, one mechanism to find them...
109 * 2. I hope that one day yangtools will actually deliver code fit for purpose in a packet
110 * processing application (presently it is not. When this happens, these can be optimized
111 * for "side-load" of pre-vetted data. Example. IP Address (v4 or v6) is prevetted left of the
112 * prefix. It should be loadable into Prefix without _RERUNNING_ 100ms+ of regexps. When (and if)
113 * that happens, it will be a simple fix here without chasing it across the whole plugin.
116 public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address) {
117 return IetfInetUtil.ipv4PrefixFor(ipv4Address);
120 public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final String mask) {
122 * Ipv4Address has already validated the address part of the prefix,
123 * It is mandated to comply to the same regexp as the address
124 * There is absolutely no point rerunning additional checks vs this
125 * Note - there is no canonical form check here!!!
127 if (null != mask && !mask.isEmpty()) {
128 return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + mask);
130 return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH);
134 public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final int intmask) {
135 return IetfInetUtil.ipv4PrefixFor(ipv4Address, intmask);
138 public static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final byte [] bytemask) {
139 if (bytemask == null) {
140 return createPrefix(ipv4Address);
143 return IetfInetUtil.ipv4PrefixFor(ipv4Address, countBits(bytemask));
146 public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address) {
147 return IetfInetUtil.ipv6PrefixFor(ipv6Address);
150 public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final String mask) {
152 * Ipv6Address has already validated the address part of the prefix,
153 * It is mandated to comply to the same regexp as the address
154 * There is absolutely no point rerunning additional checks vs this
155 * Note - there is no canonical form check here!!!
157 if (Strings.isNullOrEmpty(mask)) {
158 return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + String.valueOf(IPV6_ADDRESS_LENGTH));
160 return new Ipv6Prefix(ipv6Address.getValue() + PREFIX_SEPARATOR + mask);
164 public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final int intmask) {
165 return IetfInetUtil.ipv6PrefixFor(ipv6Address, intmask);
168 public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address, final byte [] bytemask) {
169 if (bytemask == null) {
170 return createPrefix(ipv6Address);
173 return IetfInetUtil.ipv6PrefixFor(ipv6Address, countBits(bytemask));
176 public static DottedQuad createArbitraryBitMask(final byte[] bitmask) {
177 if (bitmask == null) {
178 return IPV4_BITMASKS[IPV4_ADDRESS_LENGTH];
181 final String hostAddress;
183 hostAddress = InetAddress.getByAddress(bitmask).getHostAddress();
184 } catch (UnknownHostException e) {
185 LOG.error("Failed to create the dottedQuad notation for the given mask {}", Arrays.toString(bitmask), e);
189 return new DottedQuad(hostAddress);
192 public static Ipv6ArbitraryMask createIpv6ArbitraryBitMask(final byte[] bitmask) {
193 if (bitmask == null) {
194 return DEFAULT_IPV6_ARBITRARY_BITMASK;
197 final String hostAddress;
199 hostAddress = InetAddress.getByAddress(bitmask).getHostAddress();
200 } catch (UnknownHostException e) {
201 LOG.error("Failed to create the Ipv6ArbitraryMask notation for the given mask {}", Arrays.toString(bitmask),
206 return new Ipv6ArbitraryMask(hostAddress);
209 public static Integer extractPrefix(final Ipv4Prefix ipv4Prefix) {
210 return IetfInetUtil.splitIpv4Prefix(ipv4Prefix).getValue();
213 public static Integer extractPrefix(final Ipv6Prefix ipv6Prefix) {
214 return IetfInetUtil.splitIpv6Prefix(ipv6Prefix).getValue();
217 public static Integer extractPrefix(final Ipv4Address ipv4Prefix) {
218 return IPV4_ADDRESS_LENGTH;
221 public static Integer extractPrefix(final Ipv6Address ipv6Prefix) {
226 * Check if the supplied Ipv4Prefix has a prefix shorter than IPv4 address length.
228 * @param ipv4Prefix Ipv4 prefix
229 * @return prefix if there is one, else null
231 public static Integer hasIpv4Prefix(final Ipv4Prefix ipv4Prefix) {
232 return hasPrefix(extractPrefix(ipv4Prefix), IPV4_ADDRESS_LENGTH);
235 private static Integer hasPrefix(final Integer prefix, final int addressLength) {
236 return prefix != null && prefix < addressLength ? prefix : null;
239 public static int maskForIpv4Prefix(final int prefixLength) {
240 return (int) (0xffffffffL << IPV4_ADDRESS_LENGTH - prefixLength);
245 * Read all of the following before you touch any v6 code or decide to
246 * optimize it by invoking a "simple" Guava call
248 * Java IPv6 is fundamentally broken and Google libraries do not fix it.
249 * 1. Java will allways implicitly rewrite v4 mapped into v6 as a v4 address
250 * and there is absolutely no way to override this behaviour
251 * 2. Guava libraries cannot parse non-canonical IPv6. They will throw an
252 * exception. Even if they did, they re-use the same broken java code
255 * This is why we have to parse v6 by ourselves.
257 * The following conversion code is based on inet_cidr_pton_ipv6 in NetBSD
259 * The original BSD code is licensed under standard BSD license. While we
260 * are not obliged to provide an attribution, credit where credit is due.
261 * As far as why it is similar to Sun's sun.net.util please ask Sun why
262 * their code has the same variable names, comments and code flow.
268 * Convert Ipv6Address object to a valid Canonical v6 address in byte format.
270 * @param ipv6Address - v6 Address object
271 * @return - byte array of size 16. Last byte contains netmask
273 public static byte[] canonicalBinaryV6Address(final Ipv6Address ipv6Address) {
275 * Do not modify this routine to take direct strings input!!!
276 * Key checks have been removed based on the assumption that
277 * the input is validated via regexps in Ipv6Prefix()
280 return canonicalBinaryV6AddressFromString(ipv6Address.getValue());
284 private static byte[] canonicalBinaryV6AddressFromString(final String ipv6Address) {
285 List<String> partsV6Address = PERCENT_SPLITTER.splitToList(ipv6Address);
291 /* Isn't it fun - the above variable names are the same in BSD and Sun sources */
293 char[] src = partsV6Address.get(0).toCharArray();
295 byte[] dst = new byte[INADDR6SZ];
301 /* Leading :: requires some special handling. */
303 /* Isn't it fun - the above comment is again the same in BSD and Sun sources,
304 * We will derive our code from BSD. Shakespear always sounds better
305 * in original Clingon. So does Dilbert.
308 if (src[index1] == ':') {
309 Preconditions.checkArgument(src[++index1] == ':', "Invalid v6 address");
315 int srcLength = src.length;
317 while (index1 < srcLength) {
319 int chval = Character.digit(ch, 16);
321 /* Business as usual - ipv6 address digit.
322 * We can remove all checks from the original BSD code because
323 * the regexp has already verified that we are not being fed
324 * anything bigger than 0xffff between the separators.
339 /* no need to check separator position validity - regexp does that */
344 /* removed overrun check - the regexp checks for valid data */
346 dst[index2++] = (byte) (val >>> 8 & 0xff);
347 dst[index2++] = (byte) (val & 0xff);
353 /* frankenstein - v4 attached to v6, mixed notation */
355 if (ch == '.' && index2 + INADDR4SZ <= INADDR6SZ) {
357 /* this has passed the regexp so it is fairly safe to parse it
358 * straight away. As v4 addresses do not suffer from the same
359 * defficiencies as the java v6 implementation we can invoke it
360 * straight away and be done with it
363 Preconditions.checkArgument(index2 != INADDR6SZ - INADDR4SZ - 1, "Invalid v4 in v6 mapping");
365 InetAddress inetForm = InetAddresses.forString(partsV6Address.get(0).substring(curtok, srcLength));
367 Preconditions.checkArgument(inetForm instanceof Inet4Address);
368 System.arraycopy(inetForm.getAddress(), 0, dst, index2, INADDR4SZ);
374 /* removed parser exit on invalid char - no need to do it, regexp checks it */
377 Preconditions.checkArgument(index2 + INT16SZ <= INADDR6SZ, "Overrun in v6 parsing, should not occur");
378 dst[index2++] = (byte) (val >> 8 & 0xff);
379 dst[index2++] = (byte) (val & 0xff);
383 int to = index2 - colonp;
385 Preconditions.checkArgument(index2 != INADDR6SZ, "Overrun in v6 parsing, should not occur");
386 for (index1 = 1; index1 <= to; index1++) {
387 dst[INADDR6SZ - index1] = dst[colonp + to - index1];
388 dst[colonp + to - index1] = 0;
393 Preconditions.checkArgument(index2 == INADDR6SZ, "Overrun in v6 parsing, should not occur");
398 public static String byteArrayV6AddressToString(final byte [] binaryForm) throws UnknownHostException {
399 /* DO NOT DIY!!! - InetAddresses will actually print correct canonical
400 * zero compressed form.
402 return InetAddresses.toAddrString(InetAddress.getByAddress(binaryForm));
405 private static int nextNibble(final int mask) {
412 return 0xff << 8 - mask;
416 * Convert Ipv6Prefix object to a valid Canonical v6 prefix in byte format.
418 * @param ipv6Prefix - v6 prefix object
419 * @return - byte array of size 16 + 1. Last byte contains netmask
421 public static byte[] canonicalBinaryV6Prefix(final Ipv6Prefix ipv6Prefix) {
423 * Do not modify this routine to take direct strings input!!!
424 * Key checks have been removed based on the assumption that
425 * the input is validated via regexps in Ipv6Prefix()
428 int initialMask = 128;
430 List<String> partsV6Prefix = PREFIX_TRIM_SPLITTER.splitToList(ipv6Prefix.getValue());
432 boolean valid = true;
435 initialMask = Integer.parseInt(partsV6Prefix.get(1));
436 if (initialMask > 128) {
439 } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
443 Preconditions.checkArgument(valid, "Supplied netmask in %s is invalid", ipv6Prefix.getValue());
450 /* Isn't it fun - the above variable names are the same in BSD and Sun sources */
452 char[] src = partsV6Prefix.get(0).toCharArray();
454 byte[] dst = new byte[INADDR6SZ + 1];
456 int mask = initialMask;
462 /* Leading :: requires some special handling. */
464 /* Isn't it fun - the above comment is again the same in BSD and Sun sources,
465 * We will derive our code from BSD. Shakespear always sounds better
466 * in original Clingon. So does Dilbert.
469 if (src[index1] == ':') {
470 Preconditions.checkArgument(src[++index1] == ':', "Invalid v6 address");
476 int srcLength = src.length;
478 while (index1 < srcLength) {
480 int chval = Character.digit(ch, 16);
482 /* Business as usual - ipv6 address digit.
483 * We can remove all checks from the original BSD code because
484 * the regexp has already verified that we are not being fed
485 * anything bigger than 0xffff between the separators.
500 /* no need to check separator position validity - regexp does that */
505 /* removed overrun check - the regexp checks for valid data */
510 /* stop parsing if we are past the mask */
514 dst[index2] = (byte) (val >> 8 & nextNibble(mask));
519 /* stop parsing if we are past the mask */
523 dst[index2] = (byte) (val & nextNibble(mask));
531 /* frankenstein - v4 attached to v6, mixed notation */
533 if (ch == '.' && index2 + INADDR4SZ <= INADDR6SZ) {
535 /* this has passed the regexp so it is fairly safe to parse it
536 * straight away. As v4 addresses do not suffer from the same
537 * defficiencies as the java v6 implementation we can invoke it
538 * straight away and be done with it
541 Preconditions.checkArgument(index2 != INADDR6SZ - INADDR4SZ - 1, "Invalid v4 in v6 mapping");
543 InetAddress inetForm = InetAddresses.forString(partsV6Prefix.get(0).substring(curtok, srcLength));
545 Preconditions.checkArgument(inetForm instanceof Inet4Address);
546 System.arraycopy(inetForm.getAddress(), 0, dst, index2, INADDR4SZ);
552 /* removed parser exit on ivalid char - no need to do it, regexp checks it */
555 Preconditions.checkArgument(index2 + INT16SZ <= INADDR6SZ, "Overrun in v6 parsing, should not occur");
556 dst[index2] = (byte) (val >> 8 & nextNibble(mask));
559 dst[index2] = (byte) (val & nextNibble(mask));
564 if (index2 < INADDR6SZ && mask < 0) {
566 for (index1 = index2; index1 < INADDR6SZ; index1++) {
572 int to = index2 - colonp;
574 Preconditions.checkArgument(index2 != INADDR6SZ, "Overrun in v6 parsing, should not occur");
575 for (index1 = 1; index1 <= to; index1++) {
576 dst[INADDR6SZ - index1] = dst[colonp + to - index1];
577 dst[colonp + to - index1] = 0;
581 Preconditions.checkArgument(index2 == INADDR6SZ, "Overrun in v6 parsing, should not occur");
584 dst[INADDR6SZ] = (byte) initialMask;
589 * Print a v6 prefix in byte array + 1 notation.
591 * @param binaryForm - prefix, in byte [] form, last byte is netmask
592 * @return string of v6 prefix
593 * @throws UnknownHostException unknown host exception
595 public static String byteArrayV6PrefixToString(final byte [] binaryForm) throws UnknownHostException {
596 /* NO DIY!!! - InetAddresses will actually print correct canonical
597 * zero compressed form
599 StringBuilder sb = new StringBuilder();
600 /* Yang RFC specifies that the normalized form is RFC 5952, note - java
601 * core type is not RFC compliant, guava is.
604 InetAddresses.toAddrString(
605 InetAddress.getByAddress(
606 Arrays.copyOf(binaryForm, INADDR6SZ)
611 sb.append(binaryForm[INADDR6SZ] & 0xff);
612 return sb.toString();
616 * Check if the supplied Ipv6Prefix has a prefix shorter than IPv6 address length.
618 * @param ipv6Prefix Ipv6 prefix
619 * @return prefix if there is one, else null
621 public static Integer hasIpv6Prefix(final Ipv6Prefix ipv6Prefix) {
622 return hasPrefix(extractIpv6Prefix(ipv6Prefix), IPV6_ADDRESS_LENGTH);
625 private static int ipv6PrefixByteArrayOffset(final int mask) {
630 final int ret = mask * INADDR6SZ;
631 if (ret < PREFIX_BYTEARRAYS.length) {
634 return PREFIX_BYTEARRAYS.length - INADDR6SZ;
639 * Canonicalize a v6 prefix while in binary form.
641 * @param prefix - prefix, in byte [] form
642 * @param mask - mask - number of bits
644 public static void canonicalizeIpv6Prefix(final byte [] prefix, final int mask) {
645 final int offset = ipv6PrefixByteArrayOffset(mask);
647 for (int i = 0; i < INADDR6SZ; i++) {
648 prefix[i] &= PREFIX_BYTEARRAYS[offset + i];
652 public static byte[] convertIpv6PrefixToByteArray(final int prefix) {
653 final int offset = ipv6PrefixByteArrayOffset(prefix);
655 return Arrays.copyOfRange(PREFIX_BYTEARRAYS, offset, offset + INADDR6SZ);
658 public static Ipv6Address extractIpv6Address(final Ipv6Prefix ipv6Prefix) {
659 return IetfInetUtil.ipv6AddressFrom(ipv6Prefix);
662 public static Ipv4Address extractIpv4Address(final Ipv4Prefix ipv4Prefix) {
663 return IetfInetUtil.ipv4AddressFrom(ipv4Prefix);
666 public static DottedQuad extractIpv4AddressMask(final Ipv4Prefix ipv4Prefix) {
667 final String value = ipv4Prefix.getValue();
668 return IPV4_BITMASKS[Integer.parseInt(value.substring(value.indexOf('/') + 1))];
672 public static Ipv6ArbitraryMask extractIpv6AddressMask(final Ipv6Prefix ipv6Prefix) {
673 Iterator<String> addressParts = PREFIX_SPLITTER.split(ipv6Prefix.getValue()).iterator();
676 if (addressParts.hasNext()) {
677 maskLength = Integer.parseInt(addressParts.next());
679 BitSet ipmask = new BitSet(128);
680 ipmask.set(0,maskLength,true);
681 ipmask.set(maskLength + 1,128,false);
682 byte[] finalmask = new byte[16];
683 System.arraycopy(ipmask.toByteArray(),0,finalmask,0,ipmask.toByteArray().length);
684 InetAddress inetAddress = null;
686 inetAddress = InetAddress.getByAddress(finalmask);
687 } catch (UnknownHostException e) {
688 LOG.error("Failed to convert the Ipv6 subnetmask from integer to mask value ", e);
691 return new Ipv6ArbitraryMask(inetAddress.getHostAddress());
694 public static Integer extractIpv6Prefix(final Ipv6Prefix ipv6Prefix) {
695 return IetfInetUtil.splitIpv6Prefix(ipv6Prefix).getValue();
698 public static int countBits(final byte[] mask) {
700 for (byte b : mask) {
701 netmask += Integer.bitCount(UnsignedBytes.toInt(b));
706 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
707 public static byte @Nullable[] convertArbitraryMaskToByteArray(final DottedQuad mask) {
708 final String maskValue;
709 if (mask != null && mask.getValue() != null) {
710 maskValue = mask.getValue();
712 maskValue = IPV4_BITMASKS[IPV4_ADDRESS_LENGTH].getValue();
715 final InetAddress maskInIpFormat;
717 maskInIpFormat = InetAddress.getByName(maskValue);
718 } catch (UnknownHostException e) {
719 LOG.error("Failed to resolve the ip address of the mask ", e);
722 byte[] bytes = maskInIpFormat.getAddress();
726 public static boolean isArbitraryBitMask(final byte[] byteMask) {
727 return isArbitraryBitMask(byteMask, IPV4_ADDRESS_LENGTH);
730 private static boolean isArbitraryBitMask(final byte[] byteMask, final int addressLength) {
731 if (byteMask == null) {
735 ArrayList<Integer> integerMaskArrayList = new ArrayList<>();
737 // converting byte array to bits
738 maskInBits = new BigInteger(1, byteMask).toString(2);
739 for (String string : BITMASK_SPLIT_PATTERN.split(maskInBits)) {
740 integerMaskArrayList.add(Integer.parseInt(string));
743 final int size = integerMaskArrayList.size();
744 // checks 0*1* case - Leading zeros in arrayList are truncated
745 if (size > 0 && size < addressLength) {
750 for (int i = 0; i < size - 1; i++) {
751 if (integerMaskArrayList.get(i) == 0 && integerMaskArrayList.get(i + 1) == 1) {
758 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
759 public static byte @Nullable[] convertIpv6ArbitraryMaskToByteArray(final Ipv6ArbitraryMask mask) {
760 final String maskValue;
761 if (mask != null && mask.getValue() != null) {
762 maskValue = mask.getValue();
764 maskValue = DEFAULT_IPV6_ARBITRARY_BITMASK.getValue();
767 final InetAddress maskInIpFormat;
769 maskInIpFormat = InetAddress.getByName(maskValue);
770 } catch (UnknownHostException e) {
771 LOG.error("Failed to convert mask string to ipv6 format mask ",e);
774 return maskInIpFormat.getAddress();
777 public static boolean isIpv6ArbitraryBitMask(final byte[] byteMask) {
778 return isArbitraryBitMask(byteMask, IPV6_ADDRESS_LENGTH);
781 private static String compressedIpv6FormatFromString(final String ipv6Address) {
783 return byteArrayV6AddressToString(canonicalBinaryV6AddressFromString(ipv6Address));
784 } catch (UnknownHostException e) {
785 LOG.warn("Failed to compress IPv6 address {} because it is invalid", ipv6Address);
790 public static Ipv6Address compressedIpv6AddressFormat(final Ipv6Address ipv6Address) {
791 return new Ipv6Address(compressedIpv6FormatFromString(ipv6Address.getValue()));
794 public static Ipv6ArbitraryMask compressedIpv6MaskFormat(final Ipv6ArbitraryMask ipv6Mask) {
795 return new Ipv6ArbitraryMask(compressedIpv6FormatFromString(ipv6Mask.getValue()));