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