initial import

Change-Id: Ief25aef0066ea96bd2c329ccef974c072b3a5a73
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
new file mode 100644
index 0000000..ba7eb93
--- /dev/null
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
@@ -0,0 +1,53 @@
+package org.projectfloodlight.openflow.types;
+
+
+public abstract class IPAddressWithMask<F extends IPAddress<F>> extends Masked<F> {
+
+    protected IPAddressWithMask(F value, F mask) {
+        super(value, mask);
+    }
+
+    public abstract IPVersion getIpVersion();
+
+    public F getSubnetBroadcastAddress() {
+        if (!mask.isCidrMask()) {
+            throw new IllegalArgumentException("Mask Invalid " + mask +
+                                               " cannot get subnet for non CIDR mask");
+        }
+        return value.or(mask.not());
+    }
+
+    public boolean isSubnetBroadcastAddress(F candidate) {
+        return getSubnetBroadcastAddress().equals(candidate);
+    }
+
+    public static IPAddressWithMask<?> of(String ip) {
+        if (ip == null) {
+            throw new NullPointerException("String ip must not be null");
+        }
+        if (ip.indexOf('.') != -1)
+            return IPv4AddressWithMask.of(ip);
+        else if (ip.indexOf(':') != -1)
+            return IPv6AddressWithMask.of(ip);
+        else
+            throw new IllegalArgumentException("IP Address not well formed: " + ip);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder res = new StringBuilder();
+        res.append(value.toString());
+
+        res.append('/');
+        if (mask.isCidrMask()) {
+            // CIDR notation
+            res.append(mask.asCidrMaskLength());
+        } else {
+            // Full address mask
+            res.append(mask.toString());
+        }
+
+        return res.toString();
+    }
+
+}