Adjust to odlparent 3 Checkstyle settings
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / mdsalutil / NWUtil.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.genius.mdsalutil;
9
10 import com.google.common.base.Optional;
11 import com.google.common.net.InetAddresses;
12 import com.google.common.primitives.Ints;
13 import com.google.common.primitives.UnsignedBytes;
14 import java.math.BigInteger;
15 import java.net.Inet4Address;
16 import java.net.InetAddress;
17 import java.net.UnknownHostException;
18 import java.util.LinkedList;
19 import java.util.List;
20 import java.util.Locale;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 public final class NWUtil {
32
33     private static final Logger LOG = LoggerFactory.getLogger(NWUtil.class);
34
35     private NWUtil() { }
36
37     public static  long convertInetAddressToLong(InetAddress address) {
38         byte[] ipAddressRaw = address.getAddress();
39         return ((ipAddressRaw[0] & 0xFF) << 3 * 8)
40                 + ((ipAddressRaw[1] & 0xFF) << 2 * 8)
41                 + ((ipAddressRaw[2] & 0xFF) << 1 * 8)
42                 + (ipAddressRaw[3] & 0xFF)
43                 & 0xffffffffL;
44     }
45
46     /**
47     * Converts IPv4 Address in long to String.
48     * {@link #longToIpv4(long, long)} fixes the issue of {@link MDSALUtil#longToIp(long, long)}
49     * not handling IP address greater than byte.
50     *
51     * @param ipAddress IP Address to be converted to String
52     * @param mask Network mask to be appended
53     * @return IP Address converted to String
54     */
55     public static String longToIpv4(final long ipAddress, final long mask) {
56         final StringBuilder builder = new StringBuilder(20);
57         final Inet4Address address = InetAddresses.fromInteger((int)ipAddress);
58         builder.append(address.toString());
59         if (mask != 0) {
60             builder.append("/").append(mask);
61         }
62         return builder.toString();
63     }
64
65     public static int ipAddressToInt(String ipAddr) throws UnknownHostException {
66         InetAddress subnetAddress = InetAddress.getByName(ipAddr);
67         return Ints.fromByteArray(subnetAddress.getAddress());
68     }
69
70     public static byte[] parseMacAddress(String macAddress) {
71         byte cur;
72
73         String[] addressPart = macAddress.split(NwConstants.MACADDR_SEP);
74         int size = addressPart.length;
75
76         byte[] part = new byte[size];
77         for (int i = 0; i < size; i++) {
78             cur = UnsignedBytes.parseUnsignedByte(addressPart[i], 16);
79             part[i] = cur;
80         }
81
82         return part;
83     }
84
85     public static String toStringIpAddress(byte[] ipAddress) {
86         if (ipAddress == null) {
87             return "";
88         }
89
90         try {
91             return InetAddress.getByAddress(ipAddress).getHostAddress();
92         } catch (UnknownHostException e) {
93             // educated guess on separator
94             String sep = ipAddress.length <= 4 ? NwConstants.IPV4_SEP : NwConstants.IPV6_SEP;
95             StringBuilder sb = new StringBuilder(ipAddress.length * 2);
96             for (byte b : ipAddress) {
97                 sb.append(b).append(sep);
98             }
99             LOG.error("toStringIpAddress: Unable to translate byte[]={} to String representation",
100                       sb.deleteCharAt(sb.lastIndexOf(sep)).toString(), e);
101         }
102
103         return "";
104     }
105
106     /**
107      * Accepts a MAC address and returns the corresponding long, where the MAC
108      * bytes are set on the lower order bytes of the long.
109      *
110      * @return a long containing the mac address bytes
111      */
112     public static long macByteToLong(byte[] macAddress) {
113         long mac = 0;
114         for (int i = 0; i < 6; i++) {
115             long temp = (macAddress[i] & 0xffL) << (5 - i) * 8;
116             mac |= temp;
117         }
118         return mac;
119     }
120
121     /**
122      * Accepts a MAC address of the form 00:aa:11:bb:22:cc, case does not
123      * matter, and returns the corresponding long, where the MAC bytes are set
124      * on the lower order bytes of the long.
125      *
126      * @param macAddress
127      *            in String format
128      * @return a long containing the mac address bytes
129      */
130     public static long macToLong(MacAddress macAddress) {
131         return macByteToLong(parseMacAddress(macAddress.getValue()));
132     }
133
134     public static String toStringMacAddress(byte[] macAddress) {
135         if (macAddress == null) {
136             return "";
137         }
138
139         StringBuilder sb = new StringBuilder(18);
140
141         for (byte macAddres : macAddress) {
142             String tmp = UnsignedBytes.toString(macAddres, 16).toUpperCase(Locale.getDefault());
143             if (tmp.length() == 1 || macAddres == (byte) 0) {
144                 sb.append("0");
145             }
146             sb.append(tmp);
147             sb.append(NwConstants.MACADDR_SEP);
148         }
149
150         sb.setLength(17);
151         return sb.toString();
152     }
153
154     /**
155      * Returns the ids of the currently operative DPNs.
156      */
157     public static List<BigInteger> getOperativeDPNs(DataBroker dataBroker) {
158         List<BigInteger> result = new LinkedList<>();
159         InstanceIdentifier<Nodes> nodesInstanceIdentifier = InstanceIdentifier.builder(Nodes.class).build();
160         Optional<Nodes> nodesOptional = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL,
161                                                        nodesInstanceIdentifier);
162         if (!nodesOptional.isPresent()) {
163             return result;
164         }
165         Nodes nodes = nodesOptional.get();
166         List<Node> nodeList = nodes.getNode();
167         for (Node node : nodeList) {
168             NodeId nodeId = node.getId();
169             if (nodeId != null) {
170                 BigInteger dpnId = MDSALUtil.getDpnIdFromNodeName(nodeId);
171                 result.add(dpnId);
172             }
173         }
174         return result;
175     }
176
177     /**
178      * Utility API to check if the supplied ipAddress is IPv4 Address.
179      *
180      * @param ipAddress string-ified text of a possible IP address
181      * @return true if ipAddress is an IPv4Address and false otherwise
182      */
183     public static Boolean isIpv4Address(String ipAddress) {
184         try {
185             InetAddress address = InetAddress.getByName(ipAddress);
186             return address instanceof Inet4Address;
187         } catch (UnknownHostException e) {
188             final String msg = "UnknownHostException while checking whether '" + ipAddress + "' is an IPv4 address";
189             // Double LOG & re-throw anti pattern usually bad, exceptionally OK here, just to be sure this is seen:
190             LOG.error(msg, e);
191             throw new RuntimeException(msg, e);
192         }
193     }
194
195     /**
196      * Checks if a given ipAddress belongs to a specific subnet.
197      *
198      * @param ipAddress The Ip Address to check
199      * @param subnetCidr Subnet represented as string with CIDR
200      * @return true if the ipAddress belongs to the Subnet, or false if it
201      *     doesnt belong or the IpAddress string cannot be converted to an
202      *     InetAddress
203      */
204     public static boolean isIpInSubnet(int ipAddress, String subnetCidr) {
205         String[] subSplit = subnetCidr.split("/");
206         if (subSplit.length < 2) {
207             return false;
208         }
209
210         String subnetStr = subSplit[0];
211         int prefixLength = Integer.parseInt(subSplit[1]);
212         try {
213             int subnet = ipAddressToInt(subnetStr);
214             int mask = -1 << 32 - prefixLength;
215
216             return (subnet & mask) == (ipAddress & mask);
217
218         } catch (UnknownHostException ex) {
219             LOG.error("Subnet string {} not convertible to InetAdddress ", subnetStr, ex);
220             return false;
221         }
222     }
223
224     /**
225      * Utility API that returns the corresponding ipPrefix based on the ipAddress.
226      *
227      * @param ipAddress string text of an IP address
228      * @return ipAddress appended with a "/32" prefix (if IPv4), else "/128" prefix (for IPv6)
229      */
230     public static String toIpPrefix(String ipAddress) {
231         return isIpv4Address(ipAddress) ? ipAddress + NwConstants.IPV4PREFIX
232                                         : ipAddress + NwConstants.IPV6PREFIX;
233     }
234 }