2 * Copyright (c) 2016 Cisco and/or its affiliates.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package io.fd.honeycomb.translate.vpp.util;
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 import static com.google.common.base.Preconditions.checkState;
23 import com.google.common.net.InetAddresses;
24 import java.net.UnknownHostException;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.stream.Collectors;
28 import javax.annotation.Nonnull;
29 import org.apache.commons.lang3.StringUtils;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
37 * Trait providing logic for translation of ipv6-related data
39 public interface Ipv6Translator extends ByteDataTranslator {
42 * Transform Ipv6 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order
45 * @return byte array with address bytes
47 default byte[] ipv6AddressNoZoneToArray(@Nonnull final Ipv6AddressNoZone ipv6Addr) {
48 byte[] retval = new byte[16];
50 //splits address and add ommited zeros for easier parsing
51 List<String> segments = Arrays.asList(ipv6Addr.getValue().split(":"))
53 .map(segment -> StringUtils.repeat('0', 4 - segment.length()) + segment)
54 .collect(Collectors.toList());
57 for (String segment : segments) {
59 String firstPart = segment.substring(0, 2);
60 String secondPart = segment.substring(2);
62 //first part should be ommited
63 if ("00".equals(firstPart)) {
66 retval[index++] = ((byte) Short.parseShort(firstPart, 16));
69 retval[index++] = ((byte) Short.parseShort(secondPart, 16));
76 * Creates address array from address part of {@link Ipv6Prefix}
78 default byte[] ipv6AddressPrefixToArray(@Nonnull final Ipv6Prefix ipv4Prefix) {
79 checkNotNull(ipv4Prefix, "Cannot convert null prefix");
81 return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(
82 new Ipv6Address(ipv4Prefix.getValue().substring(0, ipv4Prefix.getValue().indexOf('/')))));
86 * Extracts {@link Ipv6Prefix} prefix
88 default byte extractPrefix(Ipv6Prefix data) {
89 checkNotNull(data, "Cannot extract from null");
91 return Byte.valueOf(data.getValue().substring(data.getValue().indexOf('/') + 1));
95 * Converts byte array to {@link Ipv6Prefix} with specified prefixLength
97 default Ipv6Prefix arrayToIpv6Prefix(final byte[] address, byte prefixLength) {
98 Ipv6AddressNoZone addressPart = arrayToIpv6AddressNoZone(address);
100 return new Ipv6Prefix(addressPart.getValue().concat("/").concat(String.valueOf(prefixLength)));
104 * Parse byte array returned by VPP representing an Ipv6 address. Vpp returns IP byte arrays in reversed order.
106 * @return Ipv46ddressNoZone containing string representation of IPv6 address constructed from submitted bytes. No
110 default Ipv6AddressNoZone arrayToIpv6AddressNoZone(@Nonnull byte[] ip) {
111 checkArgument(ip.length == 16, "Illegal array length");
114 return new Ipv6AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip)));
115 } catch (UnknownHostException e) {
116 throw new IllegalArgumentException("Unable to parse ipv6", e);
121 * Detects whether {@code IpAddress} is ipv6
123 default boolean isIpv6(IpAddress address) {
124 checkNotNull(address, "Address cannot be null");
126 checkState(!(address.getIpv4Address() == null && address.getIpv6Address() == null), "Invalid address");
127 return address.getIpv6Address() != null;
131 * Parse byte array returned by VPP representing an Ipv6 address. Vpp returns IP byte arrays in natural order.
133 * @return Ipv46ddressNoZone containing string representation of IPv6 address constructed from submitted bytes. No
137 default Ipv6AddressNoZone arrayToIpv6AddressNoZoneReversed(@Nonnull byte[] ip) {
138 checkArgument(ip.length == 16, "Illegal array length");
140 ip = reverseBytes(ip);
143 return new Ipv6AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip)));
144 } catch (UnknownHostException e) {
145 throw new IllegalArgumentException("Unable to parse ipv6", e);
151 * Detects whether {@code IpPrefix} is ipv6
153 default boolean isIpv6(IpPrefix address) {
154 checkNotNull(address, "Address cannot be null");
155 checkState(!(address.getIpv4Prefix() == null && address.getIpv6Prefix() == null), "Invalid address");
156 return address.getIpv6Prefix() != null;