Move ipv4/ipv6 ByteBuf utilities to Ipv{4,6}Util
[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 static com.google.common.base.Preconditions.checkArgument;
11
12 import com.google.common.net.InetAddresses;
13 import io.netty.buffer.ByteBuf;
14 import io.netty.buffer.Unpooled;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.List;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
23
24 /**
25  * Util class for creating generated Ipv6Address.
26  */
27 public final class Ipv6Util {
28     public static final int IPV6_LENGTH = 16;
29     public static final int IPV6_BITS_LENGTH = 128;
30
31     static final int PREFIX_BYTE_LENGTH = IPV6_LENGTH + 1;
32
33     private static final Ipv6Prefix EMPTY_PREFIX = new Ipv6Prefix("::/0");
34
35     private Ipv6Util() {
36         // Hidden on purpose
37     }
38
39     /**
40      * Creates uncompressed IP Address.
41      *
42      * @param ip to be uncompressed
43      * @return Ipv6Address with same, but uncompressed, value
44      */
45     public static Ipv6Address getFullForm(final Ipv6Address ip) {
46         return new Ipv6Address(InetAddresses.forString(ip.getValue()).getHostAddress());
47     }
48
49     /**
50      * Reads from ByteBuf buffer and converts bytes to Ipv6Address.
51      *
52      * @param buffer containing Ipv6 address, starting at reader index
53      * @return Ipv6Address
54      */
55     public static Ipv6Address addressForByteBuf(final ByteBuf buffer) {
56         return IetfInetUtil.INSTANCE.ipv6AddressFor(ByteArray.readBytes(buffer, IPV6_LENGTH));
57     }
58
59     /**
60      * Reads from ByteBuf buffer and converts bytes to Ipv6AddressNoZone.
61      *
62      * @param buffer containing Ipv6 address, starting at reader index
63      * @return Ipv6AddressNoZone
64      */
65     public static Ipv6AddressNoZone noZoneAddressForByteBuf(final ByteBuf buffer) {
66         return IetfInetUtil.INSTANCE.ipv6AddressNoZoneFor(ByteArray.readBytes(buffer, IPV6_LENGTH));
67     }
68
69     /**
70      * From string ipAddress creates an InetAddress and puts it into ByteBuf.
71      * @param ipAddress Ipv6 address
72      * @return ByteBuf with filled in bytes from ipAddress
73      */
74     public static ByteBuf byteBufForAddress(final Ipv6Address ipAddress) {
75         return Unpooled.wrappedBuffer(bytesForAddress(ipAddress));
76     }
77
78     /**
79      * Converts Ipv6Address to byte array.
80      *
81      * @param address Ipv6Address to be converted
82      * @return byte array
83      */
84     public static byte[] bytesForAddress(final Ipv6Address address) {
85         return IetfInetUtil.INSTANCE.ipv6AddressBytes(address);
86     }
87
88     /**
89      * Converts Ipv6Prefix to byte array. Prefix length at the end.
90      *
91      * @param prefix Ipv6Prefix to be converted
92      * @return byte array with prefix length at the end
93      */
94     public static byte[] bytesForPrefix(final Ipv6Prefix prefix) {
95         return IetfInetUtil.INSTANCE.ipv6PrefixToBytes(prefix);
96     }
97
98     /**
99      * Creates an Ipv6Prefix object from given byte array.
100      *
101      * @param bytes IPv6 address
102      * @param length prefix length
103      * @return Ipv6Prefix object
104      */
105     public static Ipv6Prefix prefixForBytes(final byte[] bytes, final int length) {
106         checkArgument(length <= bytes.length * Byte.SIZE);
107
108         final byte[] tmp;
109         if (bytes.length != IPV6_LENGTH) {
110             tmp = Arrays.copyOfRange(bytes, 0, IPV6_LENGTH);
111         } else {
112             tmp = bytes;
113         }
114
115         return IetfInetUtil.INSTANCE.ipv6PrefixFor(tmp, length);
116     }
117
118     /**
119      * Creates an Ipv6Prefix object from given ByteBuf. Prefix length is assumed to
120      * be in the left most byte of the buffer.
121      *
122      * @param buf IPv6 address
123      * @return Ipv6Prefix object
124      */
125     public static Ipv6Prefix prefixForByteBuf(final ByteBuf buf) {
126         final int prefixLength = buf.readUnsignedByte();
127         final int size = prefixLength / Byte.SIZE + (prefixLength % Byte.SIZE == 0 ? 0 : 1);
128         final int readable = buf.readableBytes();
129         checkArgument(size <= readable, "Illegal length of IP prefix: %s/%s", size, readable);
130
131         final byte[] bytes = new byte[IPV6_LENGTH];
132         buf.readBytes(bytes, 0, size);
133         return IetfInetUtil.INSTANCE.ipv6PrefixFor(bytes, prefixLength);
134     }
135
136     /**
137      * Creates a list of Ipv6 Prefixes from given byte array.
138      *
139      * @param bytes to be converted to List of Ipv6Prefixes.
140      * @return A List of Ipv6Prefixes
141      */
142     public static List<Ipv6Prefix> prefixListForBytes(final byte[] bytes) {
143         if (bytes.length == 0) {
144             return Collections.emptyList();
145         }
146         final List<Ipv6Prefix> list = new ArrayList<>();
147         int byteOffset = 0;
148         while (byteOffset < bytes.length) {
149             final int bitLength = Byte.toUnsignedInt(bytes[byteOffset]);
150             byteOffset += 1;
151             // if length == 0, default route will be added
152             if (bitLength == 0) {
153                 list.add(EMPTY_PREFIX);
154                 continue;
155             }
156             list.add(IetfInetUtil.INSTANCE.ipv6PrefixForShort(bytes, byteOffset, bitLength));
157             byteOffset += bitLength / Byte.SIZE;
158             if (bitLength % Byte.SIZE != 0) {
159                 byteOffset++;
160             }
161         }
162         return list;
163     }
164
165     /**
166      * Writes IPv6 address if not null, otherwise writes zeros to the
167      * <code>output</code> ByteBuf. ByteBuf's writerIndex is increased by 16.
168      *
169      * @param ipv6Address
170      *            IPv6 address to be written to the output.
171      * @param output
172      *            ByteBuf, where ipv6Address or zeros are written.
173      */
174     public static void writeIpv6Address(final Ipv6Address ipv6Address, final ByteBuf output) {
175         if (ipv6Address != null) {
176             output.writeBytes(bytesForAddress(ipv6Address));
177         } else {
178             output.writeZero(IPV6_LENGTH);
179         }
180     }
181
182     /**
183      * Writes IPv6 address if not null, otherwise writes zeros to the
184      * <code>output</code> ByteBuf. ByteBuf's writerIndex is increased by 16.
185      *
186      * @param ipv6Address
187      *            IPv6 address to be written to the output.
188      * @param output
189      *            ByteBuf, where ipv6Address or zeros are written.
190      */
191     public static void writeIpv6Address(final Ipv6AddressNoZone ipv6Address, final ByteBuf output) {
192         if (ipv6Address != null) {
193             output.writeBytes(IetfInetUtil.INSTANCE.ipv6AddressNoZoneBytes(ipv6Address));
194         } else {
195             output.writeZero(IPV6_LENGTH);
196         }
197     }
198
199     /**
200      * Writes IPv6 prefix if not null, otherwise writes zeros to the
201      * <code>output</code> ByteBuf. ByteBuf's writerIndex is increased by 17.
202      *
203      * @param ipv6Prefix
204      *            IPv6 prefix to be written to the output. Prefix is written in
205      *            the last byte.
206      * @param output
207      *            ByteBuf, where ipv6Prefix or zeros are written.
208      */
209     public static void writeIpv6Prefix(final Ipv6Prefix ipv6Prefix, final ByteBuf output) {
210         if (ipv6Prefix != null) {
211             output.writeBytes(bytesForPrefix(ipv6Prefix));
212         } else {
213             output.writeZero(PREFIX_BYTE_LENGTH);
214         }
215     }
216
217     public static void writeMinimalPrefix(final Ipv6Prefix ipv6Prefix, final ByteBuf output) {
218         final byte[] bytes = IetfInetUtil.INSTANCE.ipv6PrefixToBytes(ipv6Prefix);
219         Ipv4Util.writeMinimalPrefix(output, bytes, bytes[IPV6_LENGTH]);
220     }
221 }