1. Added SegmentRoutingManager so that it can spawn any required objects such as ArpHandler or IcmpHandler
 2. Added ArpHandler.java so that it handles any ICMP request for any known host

Change-Id: Ifd93318dc4c67fde2fce2fde04fa9df33d231e41
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
index c98bde8..9f0fa86 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/ArpHandler.java
@@ -11,25 +11,13 @@
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 
-import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.api.packet.IPacketListener;
 import net.onrc.onos.api.packet.IPacketService;
 import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
-import net.onrc.onos.core.main.config.IConfigInfoService;
 import net.onrc.onos.core.packet.ARP;
 import net.onrc.onos.core.packet.Ethernet;
 import net.onrc.onos.core.packet.IPv4;
@@ -39,23 +27,7 @@
 import net.onrc.onos.core.topology.Switch;
 import net.onrc.onos.core.util.SwitchPort;
 
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFMatchV3;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFOxmList;
-import org.projectfloodlight.openflow.protocol.OFType;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
-import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
-import org.projectfloodlight.openflow.types.EthType;
 import org.projectfloodlight.openflow.types.IPv4Address;
-import org.projectfloodlight.openflow.types.MacAddress;
-import org.projectfloodlight.openflow.types.OFBufferId;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.TableId;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,7 +40,7 @@
  * hosts to the controllers.
  * TODO: need to check the network config file for all hosts and packets
  */
-public class ArpHandler implements IFloodlightModule, IOFMessageListener, IPacketListener  {
+public class ArpHandler implements IPacketListener  {
 
     private static final Logger log = LoggerFactory
             .getLogger(ArpHandler.class);
@@ -78,7 +50,8 @@
     private IFlowPusherService flowPusher;
     private ITopologyService topologyService;
     private MutableTopology mutableTopology;
-    private List<ArpEntry> arpEntries;
+    //private List<ArpEntry> arpEntries;
+    private SegmentRoutingManager srManager;
 
     private static final short IDLE_TIMEOUT = 0;
     private static final short HARD_TIMEOUT = 0;
@@ -97,83 +70,33 @@
     private static final short MIN_PRIORITY = 0x0;
 
 
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        return null;
-    }
+    /*
+     * Default Constructor
+     */
+    public ArpHandler(FloodlightModuleContext context, SegmentRoutingManager segmentRoutingManager) {
 
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        l.add(IConfigInfoService.class);
-        l.add(ITopologyService.class);
-        l.add(IPacketService.class);
-        l.add(IFlowPusherService.class);
-        l.add(ITopologyService.class);
-
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
         this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
         this.packetService = context.getServiceImpl(IPacketService.class);
         this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
         this.topologyService = context.getServiceImpl(ITopologyService.class);
+        this.srManager = segmentRoutingManager;
+        this.mutableTopology = topologyService.getTopology();
+
+        packetService.registerPacketListener(this);
+        //arpEntries = new ArrayList<ArpEntry>();
 
         Log.debug("Arp Handler is initialized");
 
     }
 
     @Override
-    public String getName() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw,
-            OFMessage msg, FloodlightContext cntx) {
-
-        return Command.CONTINUE;
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
-
-        packetService.registerPacketListener(this);
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        mutableTopology = topologyService.getTopology();
-        arpEntries = new ArrayList<ArpEntry>();
-    }
-
-    @Override
     public void receive(Switch sw, Port inPort, Ethernet payload) {
         log.debug("Received a packet {} from sw {} ", payload.toString(), sw.getDpid());
 
         if (payload.getEtherType() == Ethernet.TYPE_ARP) {
 
             ARP arp = (ARP)payload.getPayload();
-            updateArpCache(arp);
+            srManager.updateArpCache(arp);
 
             if (arp.getOpCode() == ARP.OP_REQUEST) {
 
@@ -181,130 +104,9 @@
             }
 
         }
-        else if (payload.getEtherType() == Ethernet.TYPE_IPV4) {
-
-            IPv4 ipv4 = (IPv4)payload.getPayload();
-            if (ipv4.getProtocol() == IPv4.PROTOCOL_ICMP) {
-
-                addRouteToHost(sw, ipv4);
-
-            }
-
-        }
 
     }
 
-    /**
-     * Add routing rules to forward packets to known hosts
-     *
-     * @param sw Switch
-     * @param hostIp Host IP address to forwards packets to
-     */
-    private void addRouteToHost(Switch sw, IPv4 hostIp) {
-
-
-        IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
-        OFFactory factory = ofSwitch.getFactory();
-        int destinationAddress = hostIp.getDestinationAddress();
-        // Check APR entries
-        byte[] destinationMacAddress = getMacAddressFromIpAddress(destinationAddress);
-
-        // Check TopologyService
-        /*
-        for (Host host: mutableTopology.getHosts()) {
-            IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
-            if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
-                destinationMacAddress = host.getMacAddress().toBytes();
-            }
-        }
-        */
-
-        // If MAC address is not known to the host, just return
-        if (destinationMacAddress == null)
-            return;
-
-        OFOxmEthType ethTypeIp = factory.oxms()
-                .ethType(EthType.IPv4);
-        OFOxmIpv4DstMasked ipPrefix = factory.oxms()
-                .ipv4DstMasked(
-                        IPv4Address.of(destinationAddress),
-                        IPv4Address.NO_MASK); // host addr should be /32
-        OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
-        OFMatchV3 match = factory.buildMatchV3()
-                .setOxmList(oxmListSlash32).build();
-        OFAction setDmac = null;
-        OFOxmEthDst dmac = factory.oxms()
-                .ethDst(MacAddress.of(destinationMacAddress));
-        setDmac = factory.actions().buildSetField()
-                .setField(dmac).build();
-
-        OFAction decTtl = factory.actions().decNwTtl();
-
-        // Set the source MAC address with the switch MAC address
-        String switchMacAddress = sw.getStringAttribute("routerMac");
-        OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
-        OFAction setSA = factory.actions().buildSetField()
-                .setField(srcAddr).build();
-
-        List<OFAction> actionList = new ArrayList<OFAction>();
-        actionList.add(setDmac);
-        actionList.add(decTtl);
-        actionList.add(setSA);
-
-
-        /* TODO : need to check the config file for all packets
-        String subnets = sw.getStringAttribute("subnets");
-        try {
-            JSONArray arry = new JSONArray(subnets);
-            for (int i = 0; i < arry.length(); i++) {
-                String subnetIp = (String) arry.getJSONObject(i).get("subnetIp");
-                int portNo = (int) arry.getJSONObject(i).get("portNo");
-
-                if (netMatch(subnetIp, IPv4Address.of(hostIp.getDestinationAddress()).toString())) {
-                    OFAction out = factory.actions().buildOutput()
-                            .setPort(OFPort.of(portNo)).build();
-                    actionList.add(out);
-                }
-            }
-        } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-        */
-
-        // Set output port
-        net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress.valueOf(destinationMacAddress));
-        if (host != null) {
-            for (Port port: host.getAttachmentPoints()) {
-                OFAction out = factory.actions().buildOutput()
-                                .setPort(OFPort.of(port.getPortNumber().shortValue())).build();
-                actionList.add(out);
-            }
-        }
-
-        OFInstruction writeInstr = factory.instructions().buildWriteActions()
-                .setActions(actionList).build();
-
-        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
-        instructions.add(writeInstr);
-
-        OFMessage myIpEntry = factory.buildFlowAdd()
-                .setTableId(TableId.of(TABLE_IPv4_UNICAST))
-                .setMatch(match)
-                .setInstructions(instructions)
-                .setPriority(MAX_PRIORITY)
-                .setBufferId(OFBufferId.NO_BUFFER)
-                .setIdleTimeout(0)
-                .setHardTimeout(0)
-                //.setXid(getNextTransactionId())
-                .build();
-
-        log.debug("Sending 'Routing information' OF message to the switch {}.", sw.getDpid().toString());
-
-        flowPusher.add(sw.getDpid(), myIpEntry);
-
-
-    }
 
     /**
      * Send an ARP response for the ARP request to the known switches
@@ -348,68 +150,6 @@
     }
 
     /**
-     * Update ARP Cache using ARP packets
-     * It is used to set destination MAC address to forward packets to known hosts.
-     * But, it will be replace with Host information of Topology service later.
-     *
-     * @param arp APR packets to use for updating ARP entries
-     */
-    private void updateArpCache(ARP arp) {
-
-        ArpEntry arpEntry = new ArpEntry(arp.getSenderHardwareAddress(), arp.getSenderProtocolAddress());
-        // TODO: Need to check the duplication
-        arpEntries.add(arpEntry);
-    }
-
-    /**
-     * Temporary class to to keep ARP entry
-     *
-     */
-
-    private class ArpEntry {
-
-        byte[] targetMacAddress;
-        byte[] targetIpAddress;
-
-        private ArpEntry(byte[] macAddress, byte[] ipAddress) {
-            this.targetMacAddress = macAddress;
-            this.targetIpAddress = ipAddress;
-        }
-
-    }
-
-    /**
-     * Get MAC address to known hosts
-     *
-     * @param destinationAddress IP address to get MAC address
-     * @return MAC Address to given IP address
-     */
-    private byte[] getMacAddressFromIpAddress(int destinationAddress) {
-
-        // Can't we get the host IP address from the TopologyService ??
-
-        Iterator<ArpEntry> iterator = arpEntries.iterator();
-
-        IPv4Address ipAddress = IPv4Address.of(destinationAddress);
-        byte[] ipAddressInByte = ipAddress.getBytes();
-
-        while (iterator.hasNext() ) {
-            ArpEntry arpEntry = iterator.next();
-            byte[] address = arpEntry.targetIpAddress;
-
-            IPv4Address a = IPv4Address.of(address);
-            IPv4Address b = IPv4Address.of(ipAddressInByte);
-
-            if ( a.equals(b)) {
-                log.debug("Found an arp entry");
-                return arpEntry.targetMacAddress;
-            }
-        }
-
-        return null;
-    }
-
-    /**
      * The function checks if given IP matches to the given subnet mask
      *
      * @param addr - subnet address to match
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
new file mode 100644
index 0000000..5126958
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
@@ -0,0 +1,208 @@
+package net.onrc.onos.apps.segmentrouting;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.api.packet.IPacketListener;
+import net.onrc.onos.api.packet.IPacketService;
+import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
+import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPv4;
+import net.onrc.onos.core.topology.ITopologyService;
+import net.onrc.onos.core.topology.MutableTopology;
+import net.onrc.onos.core.topology.Port;
+import net.onrc.onos.core.topology.Switch;
+
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFMatchV3;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFOxmList;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmIpv4DstMasked;
+import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.OFBufferId;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.TableId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IcmpHandler implements IPacketListener {
+
+    private SegmentRoutingManager srManager;
+    private IFloodlightProviderService floodlightProvider;
+    private MutableTopology mutableTopology;
+    private IPacketService packetService;
+    private ITopologyService topologyService;
+    private static final Logger log = LoggerFactory
+            .getLogger(ArpHandler.class);
+
+    private IFlowPusherService flowPusher;
+
+    private static final int TABLE_VLAN = 0;
+    private static final int TABLE_TMAC = 1;
+    private static final int TABLE_IPv4_UNICAST = 2;
+    private static final int TABLE_MPLS = 3;
+    private static final int TABLE_META = 4;
+    private static final int TABLE_ACL = 5;
+
+    private static final short MAX_PRIORITY = (short) 0xffff;
+    private static final short SLASH_24_PRIORITY = (short) 0xfff0;
+    private static final short SLASH_16_PRIORITY = (short) 0xff00;
+    private static final short SLASH_8_PRIORITY = (short) 0xf000;
+    private static final short MIN_PRIORITY = 0x0;
+
+
+    public IcmpHandler(FloodlightModuleContext context, SegmentRoutingManager manager) {
+
+        this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+        this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
+        this.packetService = context.getServiceImpl(IPacketService.class);
+        this.topologyService = context.getServiceImpl(ITopologyService.class);
+        this.mutableTopology = topologyService.getTopology();
+
+        this.srManager = manager;
+
+        packetService.registerPacketListener(this);
+
+    }
+
+    @Override
+    public void receive(Switch sw, Port inPort, Ethernet payload) {
+
+        if (payload.getEtherType() == Ethernet.TYPE_IPV4) {
+
+            IPv4 ipv4 = (IPv4)payload.getPayload();
+            if (ipv4.getProtocol() == IPv4.PROTOCOL_ICMP) {
+
+                addRouteToHost(sw, ipv4);
+
+            }
+
+        }
+
+    }
+
+    /**
+     * Add routing rules to forward packets to known hosts
+     *
+     * @param sw Switch
+     * @param hostIp Host IP address to forwards packets to
+     */
+    private void addRouteToHost(Switch sw, IPv4 hostIp) {
+
+        IOFSwitch ofSwitch = floodlightProvider.getMasterSwitch(sw.getDpid().value());
+        OFFactory factory = ofSwitch.getFactory();
+        int destinationAddress = hostIp.getDestinationAddress();
+        // Check APR entries
+        byte[] destinationMacAddress = null;;
+
+       //         srManager.getMacAddressFromIpAddress(destinationAddress);
+
+        // Check TopologyService
+
+        for (net.onrc.onos.core.topology.Host host: mutableTopology.getHosts()) {
+            IPv4Address hostIpAddress = IPv4Address.of(host.getIpAddress());
+            if (hostIpAddress != null && hostIpAddress.getInt() == destinationAddress) {
+                destinationMacAddress = host.getMacAddress().toBytes();
+            }
+        }
+
+
+        // If MAC address is not known to the host, just return
+        if (destinationMacAddress == null)
+            return;
+
+        OFOxmEthType ethTypeIp = factory.oxms()
+                .ethType(EthType.IPv4);
+        OFOxmIpv4DstMasked ipPrefix = factory.oxms()
+                .ipv4DstMasked(
+                        IPv4Address.of(destinationAddress),
+                        IPv4Address.NO_MASK); // host addr should be /32
+        OFOxmList oxmListSlash32 = OFOxmList.of(ethTypeIp, ipPrefix);
+        OFMatchV3 match = factory.buildMatchV3()
+                .setOxmList(oxmListSlash32).build();
+        OFAction setDmac = null;
+        OFOxmEthDst dmac = factory.oxms()
+                .ethDst(MacAddress.of(destinationMacAddress));
+        setDmac = factory.actions().buildSetField()
+                .setField(dmac).build();
+
+        OFAction decTtl = factory.actions().decNwTtl();
+
+        // Set the source MAC address with the switch MAC address
+        String switchMacAddress = sw.getStringAttribute("routerMac");
+        OFOxmEthSrc srcAddr = factory.oxms().ethSrc(MacAddress.of(switchMacAddress));
+        OFAction setSA = factory.actions().buildSetField()
+                .setField(srcAddr).build();
+
+        List<OFAction> actionList = new ArrayList<OFAction>();
+        actionList.add(setDmac);
+        actionList.add(decTtl);
+        actionList.add(setSA);
+
+
+        /* TODO : need to check the config file for all packets
+        String subnets = sw.getStringAttribute("subnets");
+        try {
+            JSONArray arry = new JSONArray(subnets);
+            for (int i = 0; i < arry.length(); i++) {
+                String subnetIp = (String) arry.getJSONObject(i).get("subnetIp");
+                int portNo = (int) arry.getJSONObject(i).get("portNo");
+
+                if (netMatch(subnetIp, IPv4Address.of(hostIp.getDestinationAddress()).toString())) {
+                    OFAction out = factory.actions().buildOutput()
+                            .setPort(OFPort.of(portNo)).build();
+                    actionList.add(out);
+                }
+            }
+        } catch (JSONException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        */
+
+        // Set output port
+        net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(MACAddress.valueOf(destinationMacAddress));
+        if (host != null) {
+            for (Port port: host.getAttachmentPoints()) {
+                OFAction out = factory.actions().buildOutput()
+                                .setPort(OFPort.of(port.getPortNumber().shortValue())).build();
+                actionList.add(out);
+            }
+        }
+
+        OFInstruction writeInstr = factory.instructions().buildWriteActions()
+                .setActions(actionList).build();
+
+        List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+        instructions.add(writeInstr);
+
+        OFMessage myIpEntry = factory.buildFlowAdd()
+                .setTableId(TableId.of(TABLE_IPv4_UNICAST))
+                .setMatch(match)
+                .setInstructions(instructions)
+                .setPriority(MAX_PRIORITY)
+                .setBufferId(OFBufferId.NO_BUFFER)
+                .setIdleTimeout(0)
+                .setHardTimeout(0)
+                //.setXid(getNextTransactionId())
+                .build();
+
+        log.debug("Sending 'Routing information' OF message to the switch {}.", sw.getDpid().toString());
+
+        flowPusher.add(sw.getDpid(), myIpEntry);
+
+
+    }
+
+}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
new file mode 100644
index 0000000..aa6fbb8
--- /dev/null
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -0,0 +1,135 @@
+package net.onrc.onos.apps.segmentrouting;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.api.packet.IPacketService;
+import net.onrc.onos.core.flowprogrammer.IFlowPusherService;
+import net.onrc.onos.core.main.config.IConfigInfoService;
+import net.onrc.onos.core.packet.ARP;
+import net.onrc.onos.core.topology.ITopologyService;
+
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SegmentRoutingManager implements IFloodlightModule {
+
+    private static final Logger log = LoggerFactory
+            .getLogger(SegmentRoutingManager.class);
+
+    private List<ArpEntry> arpEntries;
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
+
+        l.add(IFloodlightProviderService.class);
+        l.add(IConfigInfoService.class);
+        l.add(ITopologyService.class);
+        l.add(IPacketService.class);
+        l.add(IFlowPusherService.class);
+        l.add(ITopologyService.class);
+
+        return l;
+
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+
+        ArpHandler aprHandler = new ArpHandler(context, this);
+        IcmpHandler icmpHandler = new IcmpHandler(context, this);
+        arpEntries = new ArrayList<ArpEntry>();
+
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
+        // TODO Auto-generated method stub
+
+    }
+
+    /**
+     * Update ARP Cache using ARP packets
+     * It is used to set destination MAC address to forward packets to known hosts.
+     * But, it will be replace with Host information of Topology service later.
+     *
+     * @param arp APR packets to use for updating ARP entries
+     */
+    public void updateArpCache(ARP arp) {
+
+        ArpEntry arpEntry = new ArpEntry(arp.getSenderHardwareAddress(), arp.getSenderProtocolAddress());
+        // TODO: Need to check the duplication
+        arpEntries.add(arpEntry);
+    }
+
+    /**
+     * Get MAC address to known hosts
+     *
+     * @param destinationAddress IP address to get MAC address
+     * @return MAC Address to given IP address
+     */
+    public byte[] getMacAddressFromIpAddress(int destinationAddress) {
+
+        // Can't we get the host IP address from the TopologyService ??
+
+        Iterator<ArpEntry> iterator = arpEntries.iterator();
+
+        IPv4Address ipAddress = IPv4Address.of(destinationAddress);
+        byte[] ipAddressInByte = ipAddress.getBytes();
+
+        while (iterator.hasNext() ) {
+            ArpEntry arpEntry = iterator.next();
+            byte[] address = arpEntry.targetIpAddress;
+
+            IPv4Address a = IPv4Address.of(address);
+            IPv4Address b = IPv4Address.of(ipAddressInByte);
+
+            if ( a.equals(b)) {
+                log.debug("Found an arp entry");
+                return arpEntry.targetMacAddress;
+            }
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Temporary class to to keep ARP entry
+     *
+     */
+    private class ArpEntry {
+
+        byte[] targetMacAddress;
+        byte[] targetIpAddress;
+
+        private ArpEntry(byte[] macAddress, byte[] ipAddress) {
+            this.targetMacAddress = macAddress;
+            this.targetIpAddress = ipAddress;
+        }
+
+    }
+
+}
diff --git a/src/main/java/net/onrc/onos/core/hostmanager/Host.java b/src/main/java/net/onrc/onos/core/hostmanager/Host.java
index 45452e0..0f20fac 100644
--- a/src/main/java/net/onrc/onos/core/hostmanager/Host.java
+++ b/src/main/java/net/onrc/onos/core/hostmanager/Host.java
@@ -48,6 +48,12 @@
     private MACAddress macAddress;
 
     /**
+     * The IP address associated with this entity.
+     */
+    private int ipAddress;
+
+
+    /**
      * The VLAN tag on this entity, or null if untagged.
      */
     private Short vlan;
@@ -81,14 +87,16 @@
      * Create a new host and its information.
      *
      * @param macAddress mac address of this host
+     * @param ipAddress ip address of this host (if any)
      * @param vlan vlan ID of this host
      * @param switchDPID switch DPID where the host is attached
      * @param switchPort port number where the host is attached
      * @param lastSeenTimestamp last packet-in time of this host
      */
-    public Host(MACAddress macAddress, Short vlan, Long switchDPID,
+    public Host(MACAddress macAddress, int ipAddress, Short vlan, Long switchDPID,
             Long switchPort, Date lastSeenTimestamp) {
         this.macAddress = macAddress;
+        this.ipAddress = ipAddress;
         this.vlan = vlan;
         this.switchDPID = switchDPID;
         this.switchPort = switchPort;
@@ -107,6 +115,10 @@
         return macAddress;
     }
 
+    public int getIpAddress() {
+        return ipAddress;
+    }
+
     public Short getVlan() {
         return vlan;
     }
@@ -135,6 +147,7 @@
         final int prime = 31;
         hashCode = 1;
         hashCode = prime * hashCode + (int) (macAddress.toLong() ^ (macAddress.toLong() >>> 32));
+        hashCode = prime * hashCode + ipAddress;
         hashCode = prime * hashCode + ((switchDPID == null) ? 0 : switchDPID.hashCode());
         hashCode = prime * hashCode + ((switchPort == null) ? 0 : switchPort.hashCode());
         hashCode = prime * hashCode + ((vlan == null) ? 0 : vlan.hashCode());
@@ -159,6 +172,9 @@
         if (!Objects.equals(macAddress, other.macAddress)) {
             return false;
         }
+        if (!Objects.equals(ipAddress, other.ipAddress)) {
+            return false;
+        }
         if (!Objects.equals(switchDPID, other.switchDPID)) {
             return false;
         }
@@ -176,6 +192,8 @@
         StringBuilder builder = new StringBuilder();
         builder.append("Host [macAddress=");
         builder.append(macAddress.toString());
+        builder.append(", ipAddressn=");
+        builder.append(ipAddress);
         builder.append(", vlan=");
         builder.append(vlan);
         builder.append(", switchDPID=");
diff --git a/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java b/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
index 155c3cf..e555ab5 100644
--- a/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
+++ b/src/main/java/net/onrc/onos/core/hostmanager/HostManager.java
@@ -23,10 +23,12 @@
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.packet.ARP;
 import net.onrc.onos.core.packet.Ethernet;
+import net.onrc.onos.core.packet.IPv4;
 import net.onrc.onos.core.topology.ITopologyService;
-import net.onrc.onos.core.topology.Port;
 import net.onrc.onos.core.topology.MutableTopology;
+import net.onrc.onos.core.topology.Port;
 import net.onrc.onos.core.util.Dpid;
 import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.PortNumberUtils;
@@ -34,6 +36,7 @@
 import org.projectfloodlight.openflow.protocol.OFMessage;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
 import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.types.IPv4Address;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -214,14 +217,26 @@
     protected Host getSourceHostFromPacket(Ethernet eth,
             long swdpid, long port) {
         MACAddress sourceMac = eth.getSourceMAC();
+        int sourceIp = 0;
+
+
+        if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
+            IPv4 ipv4 = (IPv4)eth.getPayload();
+            sourceIp = ipv4.getSourceAddress();
+        }
+        else if (eth.getEtherType() == Ethernet.TYPE_ARP) {
+            ARP arp = (ARP)eth.getPayload();
+            sourceIp = IPv4Address.of(arp.getSenderProtocolAddress()).getInt();
+        }
 
         // Ignore broadcast/multicast source
-        if (sourceMac.isBroadcast() || sourceMac.isBroadcast()) {
+        if (sourceMac.isBroadcast() || sourceMac.isMulticast()) {
             return null;
         }
 
         short vlan = eth.getVlanID();
         return new Host(sourceMac,
+                sourceIp,
                 ((vlan >= 0) ? vlan : null),
                 swdpid,
                 port,
@@ -287,6 +302,7 @@
             for (Port switchPort : host.getAttachmentPoints()) {
                 // We don't handle vlan now and multiple attachment points.
                 deleteHost = new Host(host.getMacAddress(),
+                        host.getIpAddress(),
                         null,
                         switchPort.getDpid().value(),
                         switchPort.getNumber().value(),
diff --git a/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java b/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
index 274c7ed..63ff94e 100644
--- a/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
+++ b/src/main/java/net/onrc/onos/core/topology/BaseTopologyAdaptor.java
@@ -261,7 +261,7 @@
         }
         List<Host> list = new ArrayList<>(hosts.size());
         for (HostData elm : hosts) {
-            list.add(new HostImpl(internalTopology, elm.getMac()));
+            list.add(new HostImpl(internalTopology, elm.getMac(), elm.getIp()));
         }
         return list;
     }
diff --git a/src/main/java/net/onrc/onos/core/topology/Host.java b/src/main/java/net/onrc/onos/core/topology/Host.java
index 4e0c2e4..eda41ae 100644
--- a/src/main/java/net/onrc/onos/core/topology/Host.java
+++ b/src/main/java/net/onrc/onos/core/topology/Host.java
@@ -23,6 +23,14 @@
     public MACAddress getMacAddress();
 
     /**
+     * Gets the Host IP address.
+     *
+     * @return the Host IP address.
+     */
+    public int getIpAddress();
+
+
+    /**
      * Gets the Host attachment points.
      * <p/>
      * TODO: There is only 1 attachment point right now.
diff --git a/src/main/java/net/onrc/onos/core/topology/HostData.java b/src/main/java/net/onrc/onos/core/topology/HostData.java
index d799113..e790134 100644
--- a/src/main/java/net/onrc/onos/core/topology/HostData.java
+++ b/src/main/java/net/onrc/onos/core/topology/HostData.java
@@ -1,5 +1,7 @@
 package net.onrc.onos.core.topology;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -12,7 +14,6 @@
 import net.onrc.onos.core.util.Dpid;
 import net.onrc.onos.core.util.SwitchPort;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 /**
@@ -22,6 +23,7 @@
 public class HostData extends TopologyElement<HostData> {
 
     private final MACAddress mac;
+    private final int ip;
     private List<SwitchPort> attachmentPoints;
     private long lastSeenTime;
 
@@ -31,6 +33,7 @@
     @Deprecated
     protected HostData() {
         mac = null;
+        ip = 0;
     }
 
     /**
@@ -38,8 +41,9 @@
      *
      * @param mac the MAC address to identify the host
      */
-    public HostData(MACAddress mac) {
+    public HostData(MACAddress mac, int ip) {
         this.mac = checkNotNull(mac);
+        this.ip = ip;
         this.attachmentPoints = new LinkedList<>();
     }
 
@@ -53,6 +57,7 @@
     public HostData(HostData original) {
         super(original);
         this.mac = original.mac;
+        this.ip = original.ip;
         this.attachmentPoints = new ArrayList<>(original.attachmentPoints);
         this.lastSeenTime = original.lastSeenTime;
     }
@@ -67,6 +72,15 @@
     }
 
     /**
+     * Gets the host IP address.
+     *
+     * @return the IP address.
+     */
+    public int getIp() {
+        return ip;
+    }
+
+    /**
      * Gets the switch attachment points.
      *
      * @return the switch attachment points
@@ -185,11 +199,12 @@
         HostData other = (HostData) o;
         // XXX lastSeenTime excluded from Equality condition, is it OK?
         return Objects.equals(mac, other.mac) &&
+                ip == other.ip &&
                 Objects.equals(this.attachmentPoints, other.attachmentPoints);
     }
 
     @Override
     public String toString() {
-        return "[HostData " + mac + " attachmentPoints:" + attachmentPoints + "]";
+        return "[HostData " + mac + "(ip:" + ip + ")" + " attachmentPoints:" + attachmentPoints + "]";
     }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/HostImpl.java b/src/main/java/net/onrc/onos/core/topology/HostImpl.java
index e45e015..1023806 100644
--- a/src/main/java/net/onrc/onos/core/topology/HostImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/HostImpl.java
@@ -1,9 +1,10 @@
 package net.onrc.onos.core.topology;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.util.ArrayList;
 import java.util.List;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.core.util.SwitchPort;
 
@@ -13,6 +14,7 @@
 public class HostImpl extends TopologyObject implements Host {
 
     private final MACAddress id;
+    private final int ipAddress;
 
 
     /**
@@ -24,6 +26,20 @@
     HostImpl(BaseInternalTopology topology, MACAddress mac) {
         super(topology);
         this.id = checkNotNull(mac);
+        this.ipAddress = 0;
+    }
+
+    /**
+     * Creates a Host handler object.
+     *
+     * @param topology Topology instance this object belongs to
+     * @param mac MAC address of the host
+     * @param ipv4Address IP address of ths host
+     */
+    HostImpl(BaseInternalTopology topology, MACAddress mac, int ipv4Address) {
+        super(topology);
+        this.id = checkNotNull(mac);
+        this.ipAddress = ipv4Address;
     }
 
     @Override
@@ -93,4 +109,14 @@
     public AdminStatus getStatus() {
         return AdminStatus.ACTIVE;
     }
+
+
+    /**
+     *  Returns the IP address of the Host
+     */
+    @Override
+    public int getIpAddress() {
+        // TODO Auto-generated method stub
+        return ipAddress;
+    }
 }
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
index 2ceb2d9..9efd911 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyImpl.java
@@ -10,9 +10,9 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.SortedSet;
 import java.util.TreeSet;
-import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.locks.Lock;
@@ -369,7 +369,7 @@
         }
         List<Host> list = new ArrayList<>(events.size());
         for (HostData elm : events) {
-            list.add(new HostImpl(this, elm.getMac()));
+            list.add(new HostImpl(this, elm.getMac(), elm.getIp()));
         }
         return list;
     }
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
index 5838483..c53ab76 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyPublisher.java
@@ -614,7 +614,7 @@
         SwitchPort sp = new SwitchPort(host.getSwitchDPID(), host.getSwitchPort());
         List<SwitchPort> spLists = new ArrayList<SwitchPort>();
         spLists.add(sp);
-        HostData hostData = new HostData(host.getMacAddress());
+        HostData hostData = new HostData(host.getMacAddress(), host.getIpAddress());
         hostData.setAttachmentPoints(spLists);
         hostData.setLastSeenTime(host.getLastSeenTimestamp().getTime());
         // Does not use vlan info now.