Bug-5119 - Adding support for L3 address arbitraty bit mask with Unittests coverage...
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / IpConversionUtil.java
index 1f125ef7744e6e7b926df0d5e002b96c29c80e41..5151d300c8ba8d8428e5fd8976810079af9e5a91 100644 (file)
@@ -8,30 +8,37 @@
 
 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
 
-import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.Iterators;
-import com.google.common.net.InetAddresses;
-import com.google.common.primitives.UnsignedBytes;
+import java.math.BigInteger;
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.Iterators;
+import com.google.common.net.InetAddresses;
+import com.google.common.primitives.UnsignedBytes;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
 
 
 /**
  * Created by Martin Bobak <mbobak@cisco.com> on 5.3.2015.
  * v6 routines added by Anton Ivanov on 14.6.2015
+ * Arbitrary masks by sai.marapareddy@gmail.com
  */
 public final class IpConversionUtil {
 
+    private static final Logger LOG = LoggerFactory.getLogger(IpConversionUtil.class);
     public static final String PREFIX_SEPARATOR = "/";
     public static final Splitter PREFIX_SPLITTER = Splitter.on('/');
     private static final int INADDR4SZ = 4;
@@ -39,6 +46,7 @@ public final class IpConversionUtil {
     private static final int INT16SZ = 2;
     private static final int IPV4_ADDRESS_LENGTH = 32;
     private static final int IPV6_ADDRESS_LENGTH = 128;
+    private static final String DEFAULT_ARBITRARY_BIT_MASK = "255.255.255.255";
 
     /*
      * Prefix bytearray lookup table. We concatenate the prefixes
@@ -120,6 +128,16 @@ public final class IpConversionUtil {
         return IetfInetUtil.INSTANCE.ipv4PrefixFor(ipv4Address, countBits(bytemask));
     }
 
+    public static DottedQuad createArbitraryBitMask(final byte [] bytemask)  {
+        DottedQuad dottedQuad = new DottedQuad(DEFAULT_ARBITRARY_BIT_MASK);
+        try {
+            dottedQuad = new DottedQuad(InetAddress.getByAddress(bytemask).getHostAddress());
+        } catch (UnknownHostException e) {
+            LOG.error("Failed to create the dottedQuad notation for the given mask ", e);
+        }
+        return dottedQuad;
+    }
+
     public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address){
         return IetfInetUtil.INSTANCE.ipv6PrefixFor(ipv6Address);
     }
@@ -577,4 +595,55 @@ public final class IpConversionUtil {
         }
         return netmask;
     }
+
+    public static final byte[] convertArbitraryMaskToByteArray(DottedQuad mask) {
+        String maskValue;
+        if (mask != null && mask.getValue() != null){
+           maskValue  = mask.getValue();
+        }
+        else {
+            maskValue = DEFAULT_ARBITRARY_BIT_MASK;
+        }
+        InetAddress maskInIpFormat = null;
+        try {
+            maskInIpFormat = InetAddress.getByName(maskValue);
+        } catch (UnknownHostException e) {
+            LOG.error ("Failed to resolve the ip address of the mask",e);
+        }
+        byte[] bytes = maskInIpFormat.getAddress();
+        return bytes;
+    }
+
+    public static boolean isArbitraryBitMask(byte[] byteMask) {
+        if (byteMask == null) {
+            return false;
+        }
+        else {
+            ArrayList<Integer> integerMaskArrayList = new ArrayList<Integer>();
+            String maskInBits;
+            // converting byte array to bits
+            maskInBits = new BigInteger(1, byteMask).toString(2);
+            ArrayList<String> stringMaskArrayList = new ArrayList<String>(Arrays.asList(maskInBits.split("(?!^)")));
+            for(String string:stringMaskArrayList){
+                integerMaskArrayList.add(Integer.parseInt(string));
+            }
+            return checkArbitraryBitMask(integerMaskArrayList);
+        }
+    }
+
+    private static boolean checkArbitraryBitMask(ArrayList<Integer> arrayList) {
+        // checks 0*1* case - Leading zeros in arrayList are truncated
+        if(arrayList.size()>0 && arrayList.size()<32) {
+            return true;
+        }
+        //checks 1*0*1 case
+        else {
+            for(int i=0; i<arrayList.size()-1;i++) {
+                if(arrayList.get(i) ==0 && arrayList.get(i+1) == 1) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }