Merge "Bug 611 - NlriReg supports serialization"
[bgpcep.git] / concepts / src / main / java / org / opendaylight / protocol / concepts / 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.concepts;
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
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
23 import org.opendaylight.protocol.util.ByteArray;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
27
28 /**
29  * Util class for creating generated Ipv4Address.
30  */
31 public final class Ipv4Util {
32
33     private Ipv4Util() {
34     }
35
36     public static final int IP4_LENGTH = 4;
37
38     /**
39      * Converts byte array to Inet4Address.
40      *
41      * @param bytes to be converted
42      * @return InetAddress instance
43      * @throws IllegalArgumentException if {@link UnknownHostException} is thrown.
44      */
45     private static InetAddress getAddress(final byte[] bytes) {
46         try {
47             return Inet4Address.getByAddress(bytes);
48         } catch (final UnknownHostException e) {
49             throw new IllegalArgumentException("Failed to construct IPv4 address", e);
50         }
51     }
52
53     /**
54      * Converts byte array to Ipv4Address.
55      *
56      * @param bytes to be converted to Ipv4Address
57      * @return Ipv4Address
58      */
59     public static Ipv4Address addressForBytes(final byte[] bytes) {
60         return new Ipv4Address(InetAddresses.toAddrString(getAddress(bytes)));
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 Ipv4Address address) {
70         final InetAddress a = InetAddresses.forString(address.getValue());
71         Preconditions.checkArgument(a instanceof Inet4Address);
72         return a.getAddress();
73     }
74
75     /**
76      * Returns number of minimum bytes needed to cover all bits of prefix.
77      *
78      * @param prefix
79      * @return
80      */
81     public static int getPrefixLengthBytes(final String prefix) {
82         int bits = Ipv4Util.getPrefixLength(prefix);
83         if (bits % 8 != 0) {
84             return (bits / 8) + 1;
85         }
86         return bits / 8;
87     }
88
89     /**
90      * Converts Ipv4Prefix to byte array of length equal to prefix length value.
91      *
92      * @param ipv4Prefix Ipv4Prefix to be converted
93      * @return byte array
94      */
95     public static byte[] bytesForPrefixByPrefixLength(Ipv4Prefix ipv4Prefix) {
96         return ByteArray.subByte(bytesForPrefix(ipv4Prefix), 0,
97                 getPrefixLengthBytes(ipv4Prefix.getValue()));
98     }
99
100     /**
101      * Converts Ipv4Prefix to byte array.
102      *
103      * @param prefix Ipv4Prefix to be converted
104      * @return byte array
105      */
106     public static byte[] bytesForPrefix(final Ipv4Prefix prefix) {
107         final String p = prefix.getValue();
108         final int sep = p.indexOf('/');
109         final InetAddress a = InetAddresses.forString(p.substring(0, sep));
110         Preconditions.checkArgument(a instanceof Inet4Address);
111         final byte[] bytes = a.getAddress();
112         return Bytes.concat(bytes, new byte[] { Byte.valueOf(p.substring(sep + 1, p.length())) });
113     }
114
115     /**
116      * Creates an Ipv4Prefix object from given byte array.
117      *
118      * @param bytes  IPv4 address
119      * @param length prefix length
120      * @return Ipv4Prefix object
121      */
122     public static Ipv4Prefix prefixForBytes(final byte[] bytes, final int length) {
123         Preconditions.checkArgument(length <= bytes.length * Byte.SIZE);
124         final byte[] tmp = Arrays.copyOfRange(bytes, 0, IP4_LENGTH);
125         final InetAddress a = getAddress(tmp);
126         return new Ipv4Prefix(InetAddresses.toAddrString(a) + '/' + length);
127     }
128
129     /**
130      * Creates a list of Ipv4 Prefixes from given byte array.
131      *
132      * @param bytes to be converted to List of Ipv4Prefixes.
133      * @return List<Ipv4Prefix>
134      */
135     public static List<Ipv4Prefix> prefixListForBytes(final byte[] bytes) {
136         if (bytes.length == 0) {
137             return Collections.emptyList();
138         }
139         final List<Ipv4Prefix> list = Lists.newArrayList();
140         int byteOffset = 0;
141         while (byteOffset < bytes.length) {
142             final int bitLength = UnsignedBytes.toInt(ByteArray.subByte(bytes, byteOffset, 1)[0]);
143             byteOffset += 1;
144             final int byteCount = (bitLength % Byte.SIZE != 0) ? (bitLength / Byte.SIZE) + 1 : bitLength / Byte.SIZE;
145             list.add(prefixForBytes(ByteArray.subByte(bytes, byteOffset, byteCount), bitLength));
146             byteOffset += byteCount;
147         }
148         return list;
149     }
150
151     /**
152      * Obtains prefix length from given prefix.
153      *
154      * @param prefix
155      * @return prefix length
156      */
157     public static int getPrefixLength(final IpPrefix prefix) {
158         String p = "";
159         if (prefix.getIpv4Prefix() != null) {
160             p = prefix.getIpv4Prefix().getValue();
161         } else {
162             p = prefix.getIpv6Prefix().getValue();
163         }
164         return getPrefixLength(p);
165     }
166
167     /**
168      * Obtains prefix length from given prefix.
169      *
170      * @param prefixValue value of prefix
171      * @return prefix length
172      */
173     public static int getPrefixLength(final String prefixValue) {
174         final int sep = prefixValue.indexOf('/');
175         return Integer.valueOf(prefixValue.substring(sep + 1, prefixValue.length()));
176     }
177 }