BUG-5790: BGP Test tool
[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 com.google.common.base.Preconditions;
11 import com.google.common.net.InetAddresses;
12 import com.google.common.primitives.UnsignedBytes;
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;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.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     private static final Ipv4Prefix EMPTY_PREFIX = new Ipv4Prefix("0.0.0.0/0");
35
36     private Ipv4Util() {
37         throw new UnsupportedOperationException();
38     }
39
40     /**
41      * Reads from ByteBuf buffer and converts bytes to Ipv4Address.
42      *
43      * @param buffer containing Ipv4 address, starting at reader index
44      * @return Ipv4Address
45      */
46     public static Ipv4Address addressForByteBuf(final ByteBuf buffer) {
47         return IetfInetUtil.INSTANCE.ipv4AddressFor(ByteArray.readBytes(buffer, IP4_LENGTH));
48     }
49
50     /**
51      * From string ipAddress creates an InetAddress and puts it into ByteBuf.
52      * @param ipAddress Ipv4 address
53      * @return ByteBuf with filled in bytes from ipAddress
54      */
55     public static ByteBuf byteBufForAddress(final Ipv4Address ipAddress) {
56         return Unpooled.wrappedBuffer(bytesForAddress(ipAddress));
57     }
58
59     /**
60      * Converts Ipv4Address to byte array.
61      *
62      * @param address Ipv4Address to be converted
63      * @return byte array
64      */
65     public static byte[] bytesForAddress(final Ipv4Address address) {
66         return IetfInetUtil.INSTANCE.ipv4AddressBytes(address);
67     }
68
69     public static int prefixBitsToBytes(final int bits) {
70         if (bits % Byte.SIZE != 0) {
71             return (bits / Byte.SIZE) + 1;
72         }
73         return bits / Byte.SIZE;
74     }
75
76     /**
77      * Returns number of minimum bytes needed to cover all bits of prefix.
78      *
79      * @param prefix
80      * @return
81      */
82     public static int getPrefixLengthBytes(final String prefix) {
83         return prefixBitsToBytes(Ipv4Util.getPrefixLength(prefix));
84     }
85
86     /**
87      * Converts Ipv4Prefix to byte array. Prefix length at the end.
88      *
89      * @param prefix Ipv4Prefix to be converted
90      * @return byte array with prefix length at the end
91      */
92     public static byte[] bytesForPrefix(final Ipv4Prefix prefix) {
93         return IetfInetUtil.INSTANCE.ipv4PrefixToBytes(prefix);
94     }
95
96     /**
97      * Converts Ipv4Prefix to byte array. Prefix length at the beginning.
98      * Prefix bytes are trimmed from the end to match prefix length.
99      *
100      * @param prefix Ipv4Prefix to be converted
101      * @return byte array with the prefix length at the beginning
102      *
103      * @deprecated This is inefficient, refactor code to use {@link #bytesForAddress(Ipv4Address)} or
104      *             {@link ByteBufWriteUtil#writeMinimalPrefix(Ipv4Prefix, ByteBuf)}.
105      */
106     @Deprecated
107     public static byte[] bytesForPrefixBegin(final Ipv4Prefix prefix) {
108         final byte[] addrWithPrefix = bytesForPrefix(prefix);
109         return prefixedBytes(addrWithPrefix[IP4_LENGTH], addrWithPrefix);
110     }
111
112     static byte[] prefixedBytes(final byte prefixBits, final byte[] address) {
113         if (prefixBits != 0) {
114             final int prefixBytes = prefixBitsToBytes(Byte.toUnsignedInt(prefixBits));
115             final byte[] ret = new byte[prefixBytes + 1];
116             ret[0] = prefixBits;
117             System.arraycopy(address, 0, ret, 1, prefixBytes);
118             return ret;
119         } else {
120             return new byte[] { 0 };
121         }
122     }
123
124     /**
125      * Creates an Ipv4Prefix object from given byte array.
126      *
127      * @param bytes  IPv4 address
128      * @param length prefix length
129      * @return Ipv4Prefix object
130      */
131     public static Ipv4Prefix prefixForBytes(final byte[] bytes, final int length) {
132         Preconditions.checkArgument(length <= bytes.length * Byte.SIZE);
133
134         final byte[] tmp;
135         if (bytes.length != IP4_LENGTH) {
136             tmp = Arrays.copyOfRange(bytes, 0, IP4_LENGTH);
137         } else {
138             tmp = bytes;
139         }
140
141         return IetfInetUtil.INSTANCE.ipv4PrefixFor(tmp, length);
142     }
143
144     /**
145      * Creates an Ipv4Prefix object from given ByteBuf. Prefix length is assumed to
146      * be in the left most byte of the buffer.
147      *
148      * @param buf Buffer containing serialized prefix
149      * @return Ipv4Prefix object
150      */
151     public static Ipv4Prefix prefixForByteBuf(final ByteBuf buf) {
152         final int prefixLength = buf.readByte();
153         final int size = prefixLength / Byte.SIZE + ((prefixLength % Byte.SIZE == 0) ? 0 : 1);
154         final int readable = buf.readableBytes();
155         Preconditions.checkArgument(size <= readable, "Illegal length of IP prefix: %s/%s", size, readable);
156
157         final byte[] bytes = new byte[IP4_LENGTH];
158         buf.readBytes(bytes, 0, size);
159         return IetfInetUtil.INSTANCE.ipv4PrefixFor(bytes, prefixLength);
160     }
161
162     /**
163      * Creates a list of Ipv4 Prefixes from given byte array.
164      *
165      * @param bytes to be converted to List of Ipv4Prefixes.
166      * @return A list of Ipv4Prefixes
167      */
168     public static List<Ipv4Prefix> prefixListForBytes(final byte[] bytes) {
169         if (bytes.length == 0) {
170             return Collections.emptyList();
171         }
172         final List<Ipv4Prefix> list = new ArrayList<>();
173         int byteOffset = 0;
174         while (byteOffset < bytes.length) {
175             final int bitLength = UnsignedBytes.toInt(bytes[byteOffset]);
176             byteOffset += 1;
177             // if length == 0, default route will be added
178             if (bitLength == 0) {
179                 list.add(EMPTY_PREFIX);
180                 continue;
181             }
182
183             list.add(IetfInetUtil.INSTANCE.ipv4PrefixForShort(bytes, byteOffset, bitLength));
184             byteOffset += bitLength / Byte.SIZE;
185             if (bitLength % Byte.SIZE != 0) {
186                 byteOffset++;
187             }
188
189         }
190         return list;
191     }
192
193     /**
194      * Obtains prefix length from given string prefix.
195      *
196      * @param prefixValue value of prefix
197      * @return prefix length
198      */
199     protected static int getPrefixLength(final String prefixValue) {
200         final int sep = prefixValue.indexOf('/');
201         return Integer.parseInt(prefixValue.substring(sep + 1, prefixValue.length()));
202     }
203
204     /**
205      * Converts InetAddress to IpAddress.
206      *
207      * @param inetAddress
208      * @return IpAddress
209      */
210     public static IpAddress getIpAddress(final InetAddress inetAddress) {
211         return IetfInetUtil.INSTANCE.ipAddressFor(inetAddress);
212     }
213
214     /**
215      * Converts IpAddress and PortNumber to InetSocketAddress
216      *
217      * @param ipAddress
218      * @param port
219      * @return InetSocketAddress
220      */
221     public static InetSocketAddress toInetSocketAddress(final IpAddress ipAddress, final PortNumber port) {
222         final String ipString;
223         if (ipAddress.getIpv4Address() != null) {
224             ipString = ipAddress.getIpv4Address().getValue();
225         } else {
226             ipString = ipAddress.getIpv6Address().getValue();
227         }
228         return new InetSocketAddress(InetAddresses.forString(ipString), port.getValue());
229     }
230
231     /**
232      * Increment Address
233      *
234      * @param ipv4Address String containing Ipv4Address
235      * @return String containing Ipv4Address incremented by 1
236      */
237     public static String incrementIpv4Address(final String ipv4Address) {
238         return InetAddresses.increment(InetAddresses.forString(ipv4Address)).getHostAddress();
239     }
240
241     /**
242      * Increment Address
243      *
244      * @param ipv4Address ipv4 address to be incremented
245      * @return new ipv4 address
246      */
247     public static Ipv4Address incrementIpv4Address(final Ipv4Address ipv4Address) {
248         return new Ipv4Address(incrementIpv4Address(ipv4Address.getValue()));
249     }
250
251     public static Ipv4Prefix incrementIpv4Prefix(final Ipv4Prefix ipv4Prefix) {
252         final Map.Entry<Ipv4Address, Integer> splitIpv4Prefix = IetfInetUtil.INSTANCE.splitIpv4Prefix(ipv4Prefix);
253         return IetfInetUtil.INSTANCE.ipv4PrefixFor(incrementIpv4Address(splitIpv4Prefix.getKey()), splitIpv4Prefix.getValue());
254     }
255 }