diff --git a/core/api/src/main/java/org/onlab/onos/net/host/InterfaceIpAddress.java b/core/api/src/main/java/org/onlab/onos/net/host/InterfaceIpAddress.java
new file mode 100644
index 0000000..afdfdde
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/host/InterfaceIpAddress.java
@@ -0,0 +1,157 @@
+package org.onlab.onos.net.host;
+
+import java.util.Objects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Represents a single IP address information on an interface.
+ *
+ * TODO:
+ *  - Add computation for the default broadcast address if it is not
+ *    specified
+ *  - Add explicit checks that each IP address or prefix belong to the
+ *    same IP version: IPv4/IPv6.
+ *  - Inside the copy constructor we should use copy constructors for each
+ *    field
+ */
+public class InterfaceIpAddress {
+    private final IpAddress ipAddress;
+    private final IpPrefix subnetAddress;
+    private final IpAddress broadcastAddress;
+    private final IpAddress peerAddress;
+
+    /**
+     * Copy constructor.
+     *
+     * @param other the object to copy from
+     */
+    public InterfaceIpAddress(InterfaceIpAddress other) {
+        // TODO: we should use copy constructors for each field
+        this.ipAddress = other.ipAddress;
+        this.subnetAddress = other.subnetAddress;
+        this.broadcastAddress = other.broadcastAddress;
+        this.peerAddress = other.peerAddress;
+    }
+
+    /**
+     * Constructor for a given IP address and a subnet address.
+     *
+     * @param ipAddress the IP address
+     * @param subnetAddress the IP subnet address
+     */
+    public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress) {
+        this.ipAddress = checkNotNull(ipAddress);
+        this.subnetAddress = checkNotNull(subnetAddress);
+        // TODO: Recompute the default broadcast address from the subnet
+        // address
+        this.broadcastAddress = null;
+        this.peerAddress = null;
+    }
+
+    /**
+     * Constructor for a given IP address and a subnet address.
+     *
+     * @param ipAddress the IP address
+     * @param subnetAddress the IP subnet address
+     * @param broadcastAddress the IP broadcast address. It can be used
+     * to specify non-default broadcast address
+     */
+    public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress,
+                              IpAddress broadcastAddress) {
+        this.ipAddress = checkNotNull(ipAddress);
+        this.subnetAddress = checkNotNull(subnetAddress);
+        this.broadcastAddress = broadcastAddress;
+        this.peerAddress = null;
+    }
+
+    /**
+     * Constructor for a given IP address and a subnet address.
+     *
+     * @param ipAddress the IP address
+     * @param subnetAddress the IP subnet address
+     * @param broadcastAddress the IP broadcast address. It can be used
+     * to specify non-default broadcast address. It should be null for
+     * point-to-point interfaces with a peer address
+     * @param peerAddress the peer IP address for point-to-point interfaces
+     */
+    public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress,
+                              IpAddress broadcastAddress,
+                              IpAddress peerAddress) {
+        this.ipAddress = checkNotNull(ipAddress);
+        this.subnetAddress = checkNotNull(subnetAddress);
+        this.broadcastAddress = broadcastAddress;
+        this.peerAddress = peerAddress;
+    }
+
+    /**
+     * Gets the IP address.
+     *
+     * @return the IP address
+     */
+    public IpAddress ipAddress() {
+        return ipAddress;
+    }
+
+    /**
+     * Gets the IP subnet address.
+     *
+     * @return the IP subnet address
+     */
+    public IpPrefix subnetAddress() {
+        return subnetAddress;
+    }
+
+    /**
+     * Gets the subnet IP broadcast address.
+     *
+     * @return the subnet IP broadcast address
+     */
+    public IpAddress broadcastAddress() {
+        return broadcastAddress;
+    }
+
+    /**
+     * Gets the IP point-to-point interface peer address.
+     *
+     * @return the IP point-to-point interface peer address
+     */
+    public IpAddress peerAddress() {
+        return peerAddress;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (!(other instanceof InterfaceIpAddress)) {
+            return false;
+        }
+        InterfaceIpAddress otherAddr = (InterfaceIpAddress) other;
+
+        return Objects.equals(this.ipAddress, otherAddr.ipAddress)
+            && Objects.equals(this.subnetAddress, otherAddr.subnetAddress)
+            && Objects.equals(this.broadcastAddress,
+                              otherAddr.broadcastAddress)
+            && Objects.equals(this.peerAddress, otherAddr.peerAddress);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipAddress, subnetAddress, broadcastAddress,
+                            peerAddress);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("ipAddress", ipAddress)
+            .add("subnetAddress", subnetAddress)
+            .add("broadcastAddress", broadcastAddress)
+            .add("peerAddress", peerAddress)
+            .omitNullValues().toString();
+    }
+}
diff --git a/core/api/src/test/java/org/onlab/onos/net/host/InterfaceIpAddressTest.java b/core/api/src/test/java/org/onlab/onos/net/host/InterfaceIpAddressTest.java
new file mode 100644
index 0000000..f436eca
--- /dev/null
+++ b/core/api/src/test/java/org/onlab/onos/net/host/InterfaceIpAddressTest.java
@@ -0,0 +1,241 @@
+package org.onlab.onos.net.host;
+
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests for class {@link InterfaceIpAddress}.
+ */
+public class InterfaceIpAddressTest {
+    private static final IpAddress IP_ADDRESS = IpAddress.valueOf("1.2.3.4");
+    private static final IpPrefix SUBNET_ADDRESS =
+        IpPrefix.valueOf("1.2.0.0/16");
+    private static final IpAddress BROADCAST_ADDRESS =
+        IpAddress.valueOf("1.2.0.255");         // NOTE: non-default broadcast
+    private static final IpAddress PEER_ADDRESS = IpAddress.valueOf("5.6.7.8");
+
+    private static final IpAddress IP_ADDRESS2 = IpAddress.valueOf("10.2.3.4");
+    private static final IpPrefix SUBNET_ADDRESS2 =
+        IpPrefix.valueOf("10.2.0.0/16");
+    private static final IpAddress BROADCAST_ADDRESS2 =
+        IpAddress.valueOf("10.2.0.255");        // NOTE: non-default broadcast
+    private static final IpAddress PEER_ADDRESS2 =
+        IpAddress.valueOf("50.6.7.8");
+
+    /**
+     * Tests valid class copy constructor.
+     */
+    @Test
+    public void testCopyConstructor() {
+        InterfaceIpAddress fromAddr;
+        InterfaceIpAddress toAddr;
+
+        // Regular interface address with default broadcast address
+        fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
+        toAddr = new InterfaceIpAddress(fromAddr);
+        assertThat(toAddr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16}"));
+
+        // Interface address with non-default broadcast address
+        fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                          BROADCAST_ADDRESS);
+        toAddr = new InterfaceIpAddress(fromAddr);
+        assertThat(toAddr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, broadcastAddress=1.2.0.255}"));
+
+        // Point-to-point address with peer IP address
+        fromAddr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                          PEER_ADDRESS);
+        toAddr = new InterfaceIpAddress(fromAddr);
+        assertThat(toAddr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, peerAddress=5.6.7.8}"));
+    }
+
+    /**
+     * Tests invalid class copy constructor for a null object to copy from.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testInvalidConstructorNullObject() {
+        InterfaceIpAddress fromAddr = null;
+        InterfaceIpAddress toAddr = new InterfaceIpAddress(fromAddr);
+    }
+
+    /**
+     * Tests valid class constructor for regular interface address with
+     * default broadcast address.
+     */
+    @Test
+    public void testConstructorForDefaultBroadcastAddress() {
+        InterfaceIpAddress addr =
+            new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
+        assertThat(addr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16}"));
+    }
+
+    /**
+     * Tests valid class constructor for interface address with
+     * non-default broadcast address.
+     */
+    @Test
+    public void testConstructorForNonDefaultBroadcastAddress() {
+        InterfaceIpAddress addr =
+            new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                   BROADCAST_ADDRESS);
+        assertThat(addr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, broadcastAddress=1.2.0.255}"));
+    }
+
+    /**
+     * Tests valid class constructor for point-to-point interface address with
+     * peer address.
+     */
+    @Test
+    public void testConstructorForPointToPointAddress() {
+        InterfaceIpAddress addr =
+            new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                   PEER_ADDRESS);
+        assertThat(addr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, peerAddress=5.6.7.8}"));
+    }
+
+    /**
+     * Tests getting the fields of an interface address.
+     */
+    @Test
+    public void testGetFields() {
+        InterfaceIpAddress addr;
+
+        // Regular interface address with default broadcast address
+        addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
+        assertThat(addr.ipAddress().toString(), is("1.2.3.4"));
+        assertThat(addr.subnetAddress().toString(), is("1.2.0.0/16"));
+        assertThat(addr.broadcastAddress(), is(nullValue()));   // TODO: Fix
+        assertThat(addr.peerAddress(), is(nullValue()));
+
+        // Interface address with non-default broadcast address
+        addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                      BROADCAST_ADDRESS);
+        assertThat(addr.ipAddress().toString(), is("1.2.3.4"));
+        assertThat(addr.subnetAddress().toString(), is("1.2.0.0/16"));
+        assertThat(addr.broadcastAddress().toString(), is("1.2.0.255"));
+        assertThat(addr.peerAddress(), is(nullValue()));
+
+        // Point-to-point address with peer IP address
+        addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                      PEER_ADDRESS);
+        assertThat(addr.ipAddress().toString(), is("1.2.3.4"));
+        assertThat(addr.subnetAddress().toString(), is("1.2.0.0/16"));
+        assertThat(addr.broadcastAddress(), is(nullValue()));
+        assertThat(addr.peerAddress().toString(), is("5.6.7.8"));
+    }
+
+    /**
+     * Tests equality of {@link InterfaceIpAddress}.
+     */
+    @Test
+    public void testEquality() {
+        InterfaceIpAddress addr1, addr2;
+
+        // Regular interface address with default broadcast address
+        addr1 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
+        addr2 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
+        assertThat(addr1, is(addr2));
+
+        // Interface address with non-default broadcast address
+        addr1 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                       BROADCAST_ADDRESS);
+        addr2 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                       BROADCAST_ADDRESS);
+        assertThat(addr1, is(addr2));
+
+        // Point-to-point address with peer IP address
+        addr1 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                       PEER_ADDRESS);
+        addr2 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                       PEER_ADDRESS);
+        assertThat(addr1, is(addr2));
+    }
+
+    /**
+     * Tests non-equality of {@link InterfaceIpAddress}.
+     */
+    @Test
+    public void testNonEquality() {
+        InterfaceIpAddress addr1, addr2, addr3, addr4;
+
+        // Regular interface address with default broadcast address
+        addr1 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
+        // Interface address with non-default broadcast address
+        addr2 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                       BROADCAST_ADDRESS);
+        // Point-to-point address with peer IP address
+        addr3 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                       PEER_ADDRESS);
+
+        // Test interface addresses with different properties:
+        //  - default-broadcast vs non-default broadcast
+        //   - regular vs point-to-point
+        assertThat(addr1, is(not(addr2)));
+        assertThat(addr1, is(not(addr3)));
+        assertThat(addr2, is(not(addr3)));
+
+        // Test regular interface address with default broadcast address
+        addr4 = new InterfaceIpAddress(IP_ADDRESS2, SUBNET_ADDRESS);
+        assertThat(addr1, is(not(addr4)));
+        addr4 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS2);
+        assertThat(addr1, is(not(addr4)));
+
+        // Test interface address with non-default broadcast address
+        addr4 = new InterfaceIpAddress(IP_ADDRESS2, SUBNET_ADDRESS,
+                                       BROADCAST_ADDRESS);
+        assertThat(addr2, is(not(addr4)));
+        addr4 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS2,
+                                       BROADCAST_ADDRESS);
+        assertThat(addr2, is(not(addr4)));
+        addr4 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                       BROADCAST_ADDRESS2);
+        assertThat(addr2, is(not(addr4)));
+
+        // Test point-to-point address with peer IP address
+        addr4 = new InterfaceIpAddress(IP_ADDRESS2, SUBNET_ADDRESS, null,
+                                       PEER_ADDRESS);
+        assertThat(addr3, is(not(addr4)));
+        addr4 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS2, null,
+                                       PEER_ADDRESS);
+        assertThat(addr3, is(not(addr4)));
+        addr4 = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                       PEER_ADDRESS2);
+        assertThat(addr3, is(not(addr4)));
+    }
+
+    /**
+     * Tests object string representation.
+     */
+    @Test
+    public void testToString() {
+        InterfaceIpAddress addr;
+
+        // Regular interface address with default broadcast address
+        addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS);
+        assertThat(addr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16}"));
+
+        // Interface address with non-default broadcast address
+        addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS,
+                                      BROADCAST_ADDRESS);
+        assertThat(addr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, broadcastAddress=1.2.0.255}"));
+
+        // Point-to-point address with peer IP address
+        addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS, null,
+                                      PEER_ADDRESS);
+        assertThat(addr.toString(),
+                   is("InterfaceIpAddress{ipAddress=1.2.3.4, subnetAddress=1.2.0.0/16, peerAddress=5.6.7.8}"));
+    }
+}
