Merge "Bug-612: Added ByteBufWriteUtil class"
[bgpcep.git] / util / src / main / java / org / opendaylight / protocol / util / Ipv6Util.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.util;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.Lists;
12 import com.google.common.net.InetAddresses;
13 import com.google.common.primitives.Bytes;
14 import com.google.common.primitives.UnsignedBytes;
15
16 import io.netty.buffer.ByteBuf;
17
18 import java.net.Inet6Address;
19 import java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.util.Arrays;
22 import java.util.Collections;
23 import java.util.List;
24
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
27
28 /**
29  * Util class for creating generated Ipv6Address.
30  */
31 public final class Ipv6Util {
32     private Ipv6Util() {
33     }
34
35     public static final int IPV6_LENGTH = 16;
36
37     /**
38      * Converts byte array to Inet6Address.
39      *
40      * @param bytes to be converted
41      * @return InetAddress instance
42      * @throws IllegalArgumentException if {@link UnknownHostException} is thrown.
43      */
44     private static InetAddress getAddress(final byte[] bytes) {
45         try {
46             return Inet6Address.getByAddress(bytes);
47         } catch (final UnknownHostException e) {
48             throw new IllegalArgumentException("Failed to construct IPv6 address", e);
49         }
50     }
51
52     /**
53      * Converts byte array to Ipv6Address.
54      *
55      * @param bytes to be converted to Ipv6Address
56      * @return Ipv6Address
57      */
58     public static Ipv6Address addressForBytes(final byte[] bytes) {
59         return new Ipv6Address(InetAddresses.toAddrString(getAddress(bytes)));
60     }
61
62     /**
63      * Reads from ByteBuf buffer and converts bytes to Ipv6Address.
64      *
65      * @param buffer containing Ipv6 address, starting at reader index
66      * @return Ipv4Address
67      */
68     public static Ipv6Address addressForByteBuf(final ByteBuf buffer) {
69         return addressForBytes(ByteArray.readBytes(buffer, IPV6_LENGTH));
70     }
71
72     /**
73      * Converts Ipv6Address to byte array.
74      *
75      * @param address Ipv6Address to be converted
76      * @return byte array
77      */
78     public static byte[] bytesForAddress(final Ipv6Address address) {
79         final InetAddress a = InetAddresses.forString(address.getValue());
80         Preconditions.checkArgument(a instanceof Inet6Address);
81         return a.getAddress();
82     }
83
84     /**
85      * Converts Ipv6Prefix to byte array.
86      *
87      * @param prefix Ipv6Prefix to be converted
88      * @return byte array
89      */
90     public static byte[] bytesForPrefix(final Ipv6Prefix prefix) {
91         final String p = prefix.getValue();
92         final int sep = p.indexOf('/');
93         final InetAddress a = InetAddresses.forString(p.substring(0, sep));
94         Preconditions.checkArgument(a instanceof Inet6Address);
95         final byte[] bytes = a.getAddress();
96         return Bytes.concat(bytes, new byte[] { Byte.valueOf(p.substring(sep + 1, p.length())) });
97     }
98
99     /**
100      * Converts Ipv4Prefix to byte array. Prefix length at the beginning.
101      * Prefix bytes are trimmed from the end to match prefix length.
102      *
103      * @param prefix Ipv6Prefix to be converted
104      * @return byte array with the prefix length at the beginning
105      */
106     public static byte[] bytesForPrefixBegin(final Ipv6Prefix prefix) {
107         final String p = prefix.getValue();
108         final int sep = p.indexOf('/');
109         final InetAddress a = InetAddresses.forString(p.substring(0, sep));
110         Preconditions.checkArgument(a instanceof Inet6Address);
111         final byte[] bytes = a.getAddress();
112         final int length = Ipv4Util.getPrefixLength(p);
113         return Bytes.concat(new byte[] { UnsignedBytes.checkedCast(length) }, ByteArray.subByte(bytes, 0 , Ipv4Util.getPrefixLengthBytes(p)));
114     }
115
116     /**
117      * Creates an Ipv6Prefix object from given byte array.
118      *
119      * @param bytes IPv6 address
120      * @param length prefix length
121      * @return Ipv6Prefix object
122      */
123     public static Ipv6Prefix prefixForBytes(final byte[] bytes, final int length) {
124         Preconditions.checkArgument(length <= bytes.length * Byte.SIZE);
125         final byte[] tmp = Arrays.copyOfRange(bytes, 0, IPV6_LENGTH);
126         final InetAddress a = getAddress(tmp);
127         return new Ipv6Prefix(InetAddresses.toAddrString(a) + '/' + length);
128     }
129
130     /**
131      * Creates a list of Ipv6 Prefixes from given byte array.
132      *
133      * @param bytes to be converted to List of Ipv6Prefixes.
134      * @return List<Ipv6Prefix>
135      */
136     public static List<Ipv6Prefix> prefixListForBytes(final byte[] bytes) {
137         if (bytes.length == 0) {
138             return Collections.emptyList();
139         }
140
141         final List<Ipv6Prefix> list = Lists.newArrayList();
142         int byteOffset = 0;
143         while (byteOffset < bytes.length) {
144             final int bitLength = UnsignedBytes.toInt(ByteArray.subByte(bytes, byteOffset, 1)[0]);
145             byteOffset += 1;
146             final int byteCount = (bitLength % Byte.SIZE != 0) ? (bitLength / Byte.SIZE) + 1 : bitLength / Byte.SIZE;
147             list.add(prefixForBytes(ByteArray.subByte(bytes, byteOffset, byteCount), bitLength));
148             byteOffset += byteCount;
149         }
150         return list;
151     }
152 }