ebebf60ddc735bbade8876aa14d97b23bc433529
[hc2vpp.git] /
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.translate.v3po.util;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20
21 import com.google.common.net.InetAddresses;
22 import java.net.UnknownHostException;
23 import java.util.Arrays;
24 import javax.annotation.Nonnull;
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
28 /**
29  * Trait providing logic for translation of ipv4-related data
30  */
31 public interface Ipv4Translator extends ByteDataTranslator {
32
33     /**
34      * Creates address array from address part of {@link Ipv4Prefix}
35      */
36     default byte[] ipv4AddressPrefixToArray(@Nonnull final Ipv4Prefix ipv4Prefix) {
37         checkNotNull(ipv4Prefix, "Cannot convert null prefix");
38
39         byte[] retval = new byte[4];
40         String[] address = ipv4Prefix.getValue().substring(0, ipv4Prefix.getValue().indexOf('/')).split("\\.");
41
42         for (int d = 0; d < 4; d++) {
43             retval[d] = (byte) (Short.parseShort(address[d]) & 0xff);
44         }
45         return retval;
46     }
47
48     /**
49      * Extracts {@link Ipv4Prefix} prefix
50      */
51     default byte extractPrefix(Ipv4Prefix data) {
52         checkNotNull(data, "Cannot extract from null");
53
54         return Byte.valueOf(data.getValue().substring(data.getValue().indexOf('/') + 1));
55     }
56
57     /**
58      * Converts byte array to {@link Ipv4Prefix} with specified prefixLength
59      */
60     default Ipv4Prefix arrayToIpv4Prefix(final byte[] address, byte prefixLength) {
61         Ipv4AddressNoZone addressPart = arrayToIpv4AddressNoZone(address);
62
63         return new Ipv4Prefix(addressPart.getValue().concat("/").concat(String.valueOf(prefixLength)));
64     }
65
66     /**
67      * Parse byte array returned by VPP representing an Ipv4 address. Vpp returns IP byte arrays in reversed order.
68      *
69      * @return Ipv4AddressNoZone containing string representation of IPv4 address constructed from submitted bytes. No
70      * change in order.
71      */
72     @Nonnull
73     default Ipv4AddressNoZone arrayToIpv4AddressNoZone(@Nonnull byte[] ip) {
74         // VPP sends ipv4 in a 16 byte array
75         if (ip.length == 16) {
76             ip = Arrays.copyOfRange(ip, 0, 4);
77         }
78         try {
79             // Not reversing the byte array here!! because the IP coming from VPP is in reversed byte order
80             // compared to byte order it was submitted
81             return new Ipv4AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip)));
82         } catch (UnknownHostException e) {
83             throw new IllegalArgumentException("Unable to parse ipv4", e);
84         }
85     }
86
87     /**
88      * Parse byte array returned by VPP representing an Ipv4 address. Vpp returns IP byte arrays in reversed order.
89      *
90      * @return Ipv4AddressNoZone containing string representation of IPv4 address constructed from submitted bytes. No
91      * change in order.
92      */
93     @Nonnull
94     default Ipv4AddressNoZone arrayToIpv4AddressNoZoneReversed(@Nonnull byte[] ip) {
95         // VPP sends ipv4 in a 16 byte array
96
97         if (ip.length == 16) {
98             ip = Arrays.copyOfRange(ip, 0, 4);
99         }
100
101         ip = reverseBytes(ip);
102
103         try {
104             // Not reversing the byte array here!! because the IP coming from VPP is in reversed byte order
105             // compared to byte order it was submitted
106             return new Ipv4AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip)));
107         } catch (UnknownHostException e) {
108             throw new IllegalArgumentException("Unable to parse ipv4", e);
109         }
110     }
111
112
113     /**
114      * Transform Ipv4 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order
115      * as the address.
116      *
117      * @return byte array with address bytes
118      */
119     default byte[] ipv4AddressNoZoneToArray(final Ipv4AddressNoZone ipv4Addr) {
120         return ipv4AddressNoZoneToArray(ipv4Addr.getValue());
121     }
122
123     default byte[] ipv4AddressNoZoneToArray(final String ipv4Addr) {
124         byte[] retval = new byte[4];
125         String[] dots = ipv4Addr.split("\\.");
126
127         for (int d = 0; d < 4; d++) {
128             retval[d] = (byte) (Short.parseShort(dots[d]) & 0xff);
129         }
130         return retval;
131     }
132 }