Move ipv4/ipv6 ByteBuf utilities to Ipv{4,6}Util
[bgpcep.git] / util / src / main / java / org / opendaylight / protocol / util / Ipv4Util.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.net.InetAddress;
16 import java.net.InetSocketAddress;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.Map.Entry;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
28
29 /**
30  * Util class for creating generated Ipv4Address.
31  */
32 public final class Ipv4Util {
33     public static final int IP4_LENGTH = 4;
34     public static final int IP4_BITS_LENGTH = 32;
35
36     static final int PREFIX_BYTE_LENGTH = IP4_LENGTH + 1;
37
38     private static final Ipv4Prefix EMPTY_PREFIX = new Ipv4Prefix("0.0.0.0/0");
39
40     private Ipv4Util() {
41         // Hidden on purpose
42     }
43
44     /**
45      * Reads from ByteBuf buffer and converts bytes to Ipv4Address.
46      *
47      * @param buffer containing Ipv4 address, starting at reader index
48      * @return Ipv4Address
49      */
50     public static Ipv4Address addressForByteBuf(final ByteBuf buffer) {
51         return IetfInetUtil.INSTANCE.ipv4AddressFor(ByteArray.readBytes(buffer, IP4_LENGTH));
52     }
53
54     /**
55      * Reads from ByteBuf buffer and converts bytes to Ipv4Address.
56      *
57      * @param buffer containing Ipv4 address, starting at reader index
58      * @return Ipv4AddressNoZone
59      */
60     public static Ipv4AddressNoZone noZoneAddressForByteBuf(final ByteBuf buffer) {
61         return IetfInetUtil.INSTANCE.ipv4AddressNoZoneFor(ByteArray.readBytes(buffer, IP4_LENGTH));
62     }
63
64     /**
65      * From string ipAddress creates an InetAddress and puts it into ByteBuf.
66      *
67      * @param ipAddress Ipv4 address
68      * @return ByteBuf with filled in bytes from ipAddress
69      */
70     public static ByteBuf byteBufForAddress(final Ipv4Address ipAddress) {
71         return Unpooled.wrappedBuffer(bytesForAddress(ipAddress));
72     }
73
74     /**
75      * Converts Ipv4Address to byte array.
76      *
77      * @param address Ipv4Address to be converted
78      * @return byte array
79      */
80     public static byte[] bytesForAddress(final Ipv4Address address) {
81         return IetfInetUtil.INSTANCE.ipv4AddressBytes(address);
82     }
83
84     public static int prefixBitsToBytes(final int bits) {
85         if (bits % Byte.SIZE != 0) {
86             return bits / Byte.SIZE + 1;
87         }
88         return bits / Byte.SIZE;
89     }
90
91     /**
92      * Returns number of minimum bytes needed to cover all bits of prefix.
93      */
94     public static int getPrefixLengthBytes(final String prefix) {
95         return prefixBitsToBytes(getPrefixLength(prefix));
96     }
97
98     /**
99      * Converts Ipv4Prefix to byte array. Prefix length at the end.
100      *
101      * @param prefix Ipv4Prefix to be converted
102      * @return byte array with prefix length at the end
103      */
104     public static byte[] bytesForPrefix(final Ipv4Prefix prefix) {
105         return IetfInetUtil.INSTANCE.ipv4PrefixToBytes(prefix);
106     }
107
108     /**
109      * Creates an Ipv4Prefix object from given byte array.
110      *
111      * @param bytes  IPv4 address
112      * @param length prefix length
113      * @return Ipv4Prefix object
114      */
115     public static Ipv4Prefix prefixForBytes(final byte[] bytes, final int length) {
116         checkArgument(length <= bytes.length * Byte.SIZE);
117
118         final byte[] tmp;
119         if (bytes.length != IP4_LENGTH) {
120             tmp = Arrays.copyOfRange(bytes, 0, IP4_LENGTH);
121         } else {
122             tmp = bytes;
123         }
124
125         return IetfInetUtil.INSTANCE.ipv4PrefixFor(tmp, length);
126     }
127
128     /**
129      * Creates an Ipv4Prefix object from given ByteBuf. Prefix length is assumed to
130      * be in the left most byte of the buffer.
131      *
132      * @param buf Buffer containing serialized prefix
133      * @return Ipv4Prefix object
134      */
135     public static Ipv4Prefix prefixForByteBuf(final ByteBuf buf) {
136         return prefixForByteBuf(buf, buf.readUnsignedByte());
137     }
138
139     /**
140      * Creates an Ipv4Prefix object from given ByteBuf with specified NLRI length.
141      *
142      * @param buf Buffer containing serialized prefix
143      * @param prefixLength Prefix length
144      * @return Ipv4Prefix object
145      */
146     public static Ipv4Prefix prefixForByteBuf(final ByteBuf buf, final int prefixLength) {
147         final int size = prefixLength / Byte.SIZE + (prefixLength % Byte.SIZE == 0 ? 0 : 1);
148         final int readable = buf.readableBytes();
149         checkArgument(size <= readable, "Illegal length of IP prefix: %s/%s", size, readable);
150
151         final byte[] bytes = new byte[IP4_LENGTH];
152         buf.readBytes(bytes, 0, size);
153         return IetfInetUtil.INSTANCE.ipv4PrefixFor(bytes, prefixLength);
154     }
155
156     /**
157      * Creates a list of Ipv4 Prefixes from given byte array.
158      *
159      * @param bytes to be converted to List of Ipv4Prefixes.
160      * @return A list of Ipv4Prefixes
161      */
162     public static List<Ipv4Prefix> prefixListForBytes(final byte[] bytes) {
163         if (bytes.length == 0) {
164             return Collections.emptyList();
165         }
166         final List<Ipv4Prefix> list = new ArrayList<>();
167         int byteOffset = 0;
168         while (byteOffset < bytes.length) {
169             final int bitLength = Byte.toUnsignedInt(bytes[byteOffset]);
170             byteOffset += 1;
171             // if length == 0, default route will be added
172             if (bitLength == 0) {
173                 list.add(EMPTY_PREFIX);
174                 continue;
175             }
176
177             list.add(IetfInetUtil.INSTANCE.ipv4PrefixForShort(bytes, byteOffset, bitLength));
178             byteOffset += bitLength / Byte.SIZE;
179             if (bitLength % Byte.SIZE != 0) {
180                 byteOffset++;
181             }
182
183         }
184         return list;
185     }
186
187     /**
188      * Obtains prefix length from given string prefix.
189      *
190      * @param prefixValue value of prefix
191      * @return prefix length
192      */
193     protected static int getPrefixLength(final String prefixValue) {
194         final int sep = prefixValue.indexOf('/');
195         return Integer.parseInt(prefixValue.substring(sep + 1, prefixValue.length()));
196     }
197
198     /**
199      * Converts InetAddress to IpAddress.
200      *
201      * @param inetAddress address
202      * @return IpAddress
203      */
204     public static IpAddress getIpAddress(final InetAddress inetAddress) {
205         return IetfInetUtil.INSTANCE.ipAddressFor(inetAddress);
206     }
207
208     /**
209      * Converts IpAddress and PortNumber to InetSocketAddress.
210      *
211      * @param ipAddress address
212      * @param port      number
213      * @return InetSocketAddress
214      */
215     public static InetSocketAddress toInetSocketAddress(final IpAddress ipAddress, final PortNumber port) {
216         final String ipString = toStringIP(ipAddress);
217         return new InetSocketAddress(InetAddresses.forString(ipString), port.getValue().toJava());
218     }
219
220     /**
221      * Increment Address.
222      *
223      * @param ipv4Address String containing Ipv4Address
224      * @return String containing Ipv4Address incremented by 1
225      */
226     public static String incrementIpv4Address(final String ipv4Address) {
227         return InetAddresses.increment(InetAddresses.forString(ipv4Address)).getHostAddress();
228     }
229
230     /**
231      * Increment Address.
232      *
233      * @param ipv4Address ipv4 address to be incremented
234      * @return new ipv4 address
235      */
236     public static Ipv4Address incrementIpv4Address(final Ipv4Address ipv4Address) {
237         return new Ipv4Address(incrementIpv4Address(ipv4Address.getValue()));
238     }
239
240     public static Ipv4Prefix incrementIpv4Prefix(final Ipv4Prefix ipv4Prefix) {
241         final Entry<Ipv4Address, Integer> splitIpv4Prefix = IetfInetUtil.INSTANCE.splitIpv4Prefix(ipv4Prefix);
242         return IetfInetUtil.INSTANCE.ipv4PrefixFor(incrementIpv4Address(splitIpv4Prefix.getKey()),
243                 splitIpv4Prefix.getValue());
244     }
245
246     /**
247      * Get string representation of IpAddress.
248      *
249      * @param ipAddress address
250      * @return String value of Ipv4Address or Ipv6Address
251      */
252     public static String toStringIP(final IpAddress ipAddress) {
253         if (ipAddress.getIpv4Address() != null) {
254             return ipAddress.getIpv4Address().getValue();
255         }
256         return ipAddress.getIpv6Address().getValue();
257     }
258
259
260     /**
261      * Writes IPv4 address if not null, otherwise writes zeros to the
262      * <code>output</code> ByteBuf. ByteBuf's writerIndex is increased by 4.
263      *
264      * @param ipv4Address
265      *            IPv4 address to be written to the output.
266      * @param output
267      *            ByteBuf, where ipv4Address or zeros are written.
268      */
269     public static void writeIpv4Address(final Ipv4Address ipv4Address, final ByteBuf output) {
270         if (ipv4Address != null) {
271             output.writeBytes(bytesForAddress(ipv4Address));
272         } else {
273             output.writeInt(0);
274         }
275     }
276
277     /**
278      * Writes IPv4 address if not null, otherwise writes zeros to the
279      * <code>output</code> ByteBuf. ByteBuf's writerIndex is increased by 4.
280      *
281      * @param ipv4Address
282      *            IPv4 address to be written to the output.
283      * @param output
284      *            ByteBuf, where ipv4Address or zeros are written.
285      */
286     public static void writeIpv4Address(final Ipv4AddressNoZone ipv4Address, final ByteBuf output) {
287         if (ipv4Address != null) {
288             output.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressNoZoneBytes(ipv4Address));
289         } else {
290             output.writeInt(0);
291         }
292     }
293
294     /**
295      * Writes IPv4 prefix if not null, otherwise writes zeros to the
296      * <code>output</code> ByteBuf. ByteBuf's writerIndex is increased by 5.
297      *
298      * @param ipv4Prefix
299      *            IPv4 prefix value to be written to the output. Prefix is
300      *            written in the last byte.
301      * @param output
302      *            ByteBuf, where ipv4Prefix or zeros are written.
303      */
304     public static void writeIpv4Prefix(final Ipv4Prefix ipv4Prefix, final ByteBuf output) {
305         if (ipv4Prefix != null) {
306             output.writeBytes(bytesForPrefix(ipv4Prefix));
307         } else {
308             output.writeZero(PREFIX_BYTE_LENGTH);
309         }
310     }
311
312     public static void writeMinimalPrefix(final Ipv4Prefix ipv4Prefix, final ByteBuf output) {
313         final byte[] bytes = IetfInetUtil.INSTANCE.ipv4PrefixToBytes(ipv4Prefix);
314         writeMinimalPrefix(output, bytes, bytes[IP4_LENGTH]);
315     }
316
317     static void writeMinimalPrefix(final ByteBuf output, final byte[] bytes, final byte prefixBits) {
318         output.writeByte(prefixBits);
319         output.writeBytes(bytes, 0, prefixBitsToBytes(Byte.toUnsignedInt(prefixBits)));
320     }
321 }