Merge "Bug-730: Test Vendor-Information object/tlv in message/object"
[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.collect.Lists;
12 import com.google.common.net.InetAddresses;
13 import com.google.common.primitives.Bytes;
14 import com.google.common.primitives.UnsignedBytes;
15 import io.netty.buffer.ByteBuf;
16 import java.net.Inet4Address;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.util.Arrays;
20 import java.util.Collections;
21 import java.util.List;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
25
26 /**
27  * Util class for creating generated Ipv4Address.
28  */
29 public final class Ipv4Util {
30
31     private Ipv4Util() {
32         throw new UnsupportedOperationException();
33     }
34
35     public static final int IP4_LENGTH = 4;
36
37     /**
38      * Converts byte array to Inet4Address.
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 Inet4Address.getByAddress(bytes);
47         } catch (final UnknownHostException e) {
48             throw new IllegalArgumentException("Failed to construct IPv4 address", e);
49         }
50     }
51
52     /**
53      * Converts byte array to Ipv4Address.
54      *
55      * @param bytes to be converted to Ipv4Address
56      * @return Ipv4Address
57      */
58     public static Ipv4Address addressForBytes(final byte[] bytes) {
59         return new Ipv4Address(InetAddresses.toAddrString(getAddress(bytes)));
60     }
61
62     /**
63      * Reads from ByteBuf buffer and converts bytes to Ipv4Address.
64      *
65      * @param buffer containing Ipv4 address, starting at reader index
66      * @return Ipv4Address
67      */
68     public static Ipv4Address addressForByteBuf(final ByteBuf buffer) {
69         return addressForBytes(ByteArray.readBytes(buffer, IP4_LENGTH));
70     }
71
72     /**
73      * Converts Ipv4Address to byte array.
74      *
75      * @param address Ipv4Address to be converted
76      * @return byte array
77      */
78     public static byte[] bytesForAddress(final Ipv4Address address) {
79         final InetAddress a = InetAddresses.forString(address.getValue());
80         Preconditions.checkArgument(a instanceof Inet4Address);
81         return a.getAddress();
82     }
83
84     /**
85      * Returns number of minimum bytes needed to cover all bits of prefix.
86      *
87      * @param prefix
88      * @return
89      */
90     public static int getPrefixLengthBytes(final String prefix) {
91         final int bits = Ipv4Util.getPrefixLength(prefix);
92         if (bits % 8 != 0) {
93             return (bits / 8) + 1;
94         }
95         return bits / 8;
96     }
97
98     /**
99      * Converts Ipv4Prefix to byte array of length equal to prefix length value.
100      *
101      * @param ipv4Prefix Ipv4Prefix to be converted
102      * @return byte array
103      */
104     public static byte[] bytesForPrefixByPrefixLength(final Ipv4Prefix ipv4Prefix) {
105         return ByteArray.subByte(bytesForPrefix(ipv4Prefix), 0,
106             getPrefixLengthBytes(ipv4Prefix.getValue()));
107     }
108
109     /**
110      * Converts Ipv4Prefix to byte array. Prefix length at the end.
111      *
112      * @param prefix Ipv4Prefix to be converted
113      * @return byte array with prefix length at the end
114      */
115     public static byte[] bytesForPrefix(final Ipv4Prefix prefix) {
116         final String p = prefix.getValue();
117         final int sep = p.indexOf('/');
118         final InetAddress a = InetAddresses.forString(p.substring(0, sep));
119         Preconditions.checkArgument(a instanceof Inet4Address);
120         final byte[] bytes = a.getAddress();
121         return Bytes.concat(bytes, new byte[] { Byte.valueOf(p.substring(sep + 1, p.length())) });
122     }
123
124     /**
125      * Converts Ipv4Prefix to byte array. Prefix length at the beginning.
126      * Prefix bytes are trimmed from the end to match prefix length.
127      *
128      * @param prefix Ipv4Prefix to be converted
129      * @return byte array with the prefix length at the beginning
130      */
131     public static byte[] bytesForPrefixBegin(final Ipv4Prefix prefix) {
132         final String p = prefix.getValue();
133         final int sep = p.indexOf('/');
134         final InetAddress a = InetAddresses.forString(p.substring(0, sep));
135         Preconditions.checkArgument(a instanceof Inet4Address);
136         final byte[] bytes = a.getAddress();
137         final int length = getPrefixLength(p);
138         return Bytes.concat(new byte[] { UnsignedBytes.checkedCast(length) }, ByteArray.subByte(bytes, 0 , getPrefixLengthBytes(p)));
139     }
140
141     /**
142      * Creates an Ipv4Prefix object from given byte array.
143      *
144      * @param bytes  IPv4 address
145      * @param length prefix length
146      * @return Ipv4Prefix object
147      */
148     public static Ipv4Prefix prefixForBytes(final byte[] bytes, final int length) {
149         Preconditions.checkArgument(length <= bytes.length * Byte.SIZE);
150         final byte[] tmp = Arrays.copyOfRange(bytes, 0, IP4_LENGTH);
151         final InetAddress a = getAddress(tmp);
152         return new Ipv4Prefix(InetAddresses.toAddrString(a) + '/' + length);
153     }
154
155     /**
156      * Creates a list of Ipv4 Prefixes from given byte array.
157      *
158      * @param bytes to be converted to List of Ipv4Prefixes.
159      * @return List<Ipv4Prefix>
160      */
161     public static List<Ipv4Prefix> prefixListForBytes(final byte[] bytes) {
162         if (bytes.length == 0) {
163             return Collections.emptyList();
164         }
165         final List<Ipv4Prefix> list = Lists.newArrayList();
166         int byteOffset = 0;
167         while (byteOffset < bytes.length) {
168             final int bitLength = UnsignedBytes.toInt(ByteArray.subByte(bytes, byteOffset, 1)[0]);
169             byteOffset += 1;
170             final int byteCount = (bitLength % Byte.SIZE != 0) ? (bitLength / Byte.SIZE) + 1 : bitLength / Byte.SIZE;
171             list.add(prefixForBytes(ByteArray.subByte(bytes, byteOffset, byteCount), bitLength));
172             byteOffset += byteCount;
173         }
174         return list;
175     }
176
177     /**
178      * Obtains prefix length from given prefix.
179      *
180      * @param prefix
181      * @return prefix length
182      */
183     public static int getPrefixLength(final IpPrefix prefix) {
184         String p = "";
185         if (prefix.getIpv4Prefix() != null) {
186             p = prefix.getIpv4Prefix().getValue();
187         } else {
188             p = prefix.getIpv6Prefix().getValue();
189         }
190         return getPrefixLength(p);
191     }
192
193     /**
194      * Obtains prefix length from given string prefix.
195      *
196      * @param prefixValue value of prefix
197      * @return prefix length
198      */
199     public static int getPrefixLength(final String prefixValue) {
200         final int sep = prefixValue.indexOf('/');
201         return Integer.parseInt(prefixValue.substring(sep + 1, prefixValue.length()));
202     }
203 }