From f61177a633eafea65c398b2614f18ea97831ea84 Mon Sep 17 00:00:00 2001
From: Ryan Izard <rizard@g.clemson.edu>
Date: Wed, 3 Jun 2015 10:08:36 -0400
Subject: [PATCH] Patched ARP class to use MacAddress, IPv4Address, and
 ArpOpcode, as it should. This makes it safer and avoids primitive data types.

---
 .../internal/DeviceManagerImpl.java           |   8 +-
 .../loadbalancer/LoadBalancer.java            |  21 +-
 .../net/floodlightcontroller/packet/ARP.java  | 636 +++++++++---------
 .../floodlightcontroller/packet/Ethernet.java |   4 +-
 .../core/internal/ControllerTest.java         |  11 +-
 .../internal/DeviceManagerImplTest.java       |  20 +-
 .../firewall/FirewallTest.java                |  17 +-
 .../loadbalancer/LoadBalancerTest.java        |  16 +-
 .../packet/PacketTest.java                    |  25 +-
 9 files changed, 380 insertions(+), 378 deletions(-)

diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index 7f9c02304..dbc20c0bd 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -1183,8 +1183,8 @@ public class DeviceManagerImpl implements IDeviceService, IOFMessageListener, IT
 	private IPv4Address getSrcNwAddr(Ethernet eth, MacAddress dlAddr) {
 		if (eth.getPayload() instanceof ARP) {
 			ARP arp = (ARP) eth.getPayload();
-			if ((arp.getProtocolType() == ARP.PROTO_TYPE_IP) && (MacAddress.of(arp.getSenderHardwareAddress()).equals(dlAddr))) {
-				return IPv4Address.of(arp.getSenderProtocolAddress());
+			if ((arp.getProtocolType() == ARP.PROTO_TYPE_IP) && (arp.getSenderHardwareAddress().equals(dlAddr))) {
+				return arp.getSenderProtocolAddress();
 			}
 		}
 		return IPv4Address.NONE;
@@ -1231,7 +1231,7 @@ public class DeviceManagerImpl implements IDeviceService, IOFMessageListener, IT
 
 		MacAddress dlAddr = eth.getSourceMACAddress();
 
-		MacAddress senderAddr = MacAddress.of(arp.getSenderHardwareAddress());
+		MacAddress senderAddr = arp.getSenderHardwareAddress();
 
 		if (dlAddr.equals(senderAddr)) return; // arp request
 
@@ -1243,7 +1243,7 @@ public class DeviceManagerImpl implements IDeviceService, IOFMessageListener, IT
 			return;
 
 		VlanVid vlan = VlanVid.ofVlan(eth.getVlanID());
-		IPv4Address nwSrc = IPv4Address.of(arp.getSenderProtocolAddress());
+		IPv4Address nwSrc = arp.getSenderProtocolAddress();
 
 		Entity e =  new Entity(senderAddr,
 				((vlan.getVlan() >= 0) ? vlan : null),
diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
index d9c45265c..c2d0201b6 100644
--- a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
+++ b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
@@ -190,11 +190,10 @@ public class LoadBalancer implements IFloodlightModule,
                 // retrieve arp to determine target IP address                                                       
                 ARP arpRequest = (ARP) eth.getPayload();
 
-                int targetProtocolAddress = IPv4.toIPv4Address(arpRequest
-                                                               .getTargetProtocolAddress());
+                IPv4Address targetProtocolAddress = arpRequest.getTargetProtocolAddress();
 
-                if (vipIpToId.containsKey(targetProtocolAddress)) {
-                    String vipId = vipIpToId.get(targetProtocolAddress);
+                if (vipIpToId.containsKey(targetProtocolAddress.getInt())) {
+                    String vipId = vipIpToId.get(targetProtocolAddress.getInt());
                     vipProxyArpReply(sw, pi, cntx, vipId);
                     return Command.STOP;
                 }
@@ -265,11 +264,10 @@ public class LoadBalancer implements IFloodlightModule,
         ARP arpRequest = (ARP) eth.getPayload();
         
         // have to do proxy arp reply since at this point we cannot determine the requesting application type
-        byte[] vipProxyMacBytes = vips.get(vipId).proxyMac.getBytes();
         
         // generate proxy ARP reply
         IPacket arpReply = new Ethernet()
-            .setSourceMACAddress(vipProxyMacBytes)
+            .setSourceMACAddress(vips.get(vipId).proxyMac)
             .setDestinationMACAddress(eth.getSourceMACAddress())
             .setEtherType(EthType.ARP)
             .setVlanID(eth.getVlanID())
@@ -281,13 +279,10 @@ public class LoadBalancer implements IFloodlightModule,
                 .setHardwareAddressLength((byte) 6)
                 .setProtocolAddressLength((byte) 4)
                 .setOpCode(ARP.OP_REPLY)
-                .setSenderHardwareAddress(vipProxyMacBytes)
-                .setSenderProtocolAddress(
-                        arpRequest.getTargetProtocolAddress())
-                .setTargetHardwareAddress(
-                        eth.getSourceMACAddress().getBytes())
-                .setTargetProtocolAddress(
-                        arpRequest.getSenderProtocolAddress()));
+                .setSenderHardwareAddress(vips.get(vipId).proxyMac)
+                .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
+                .setTargetHardwareAddress(eth.getSourceMACAddress())
+                .setTargetProtocolAddress(arpRequest.getSenderProtocolAddress()));
                 
         // push ARP reply out
         pushPacket(arpReply, sw, OFBufferId.NO_BUFFER, OFPort.ANY, (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT)), cntx, true);
diff --git a/src/main/java/net/floodlightcontroller/packet/ARP.java b/src/main/java/net/floodlightcontroller/packet/ARP.java
index bf3f49385..48bcd13c9 100644
--- a/src/main/java/net/floodlightcontroller/packet/ARP.java
+++ b/src/main/java/net/floodlightcontroller/packet/ARP.java
@@ -1,327 +1,333 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    Licensed under the Apache License, Version 2.0 (the "License"); you may
-*    not use this file except in compliance with the License. You may obtain
-*    a copy of the License at
-*
-*         http://www.apache.org/licenses/LICENSE-2.0
-*
-*    Unless required by applicable law or agreed to in writing, software
-*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-*    License for the specific language governing permissions and limitations
-*    under the License.
-**/
+ *    Copyright 2011, Big Switch Networks, Inc. 
+ *    Originally created by David Erickson, Stanford University
+ * 
+ *    Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *    not use this file except in compliance with the License. You may obtain
+ *    a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ *    License for the specific language governing permissions and limitations
+ *    under the License.
+ **/
 
 package net.floodlightcontroller.packet;
 
 import java.nio.ByteBuffer;
-import java.util.Arrays;
+
+import org.projectfloodlight.openflow.types.ArpOpcode;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
 
 /**
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
 public class ARP extends BasePacket {
-    public static short HW_TYPE_ETHERNET = 0x1;
-
-    public static short PROTO_TYPE_IP = 0x800;
-
-    public static short OP_REQUEST = 0x1;
-    public static short OP_REPLY = 0x2;
-    public static short OP_RARP_REQUEST = 0x3;
-    public static short OP_RARP_REPLY = 0x4;
-
-    protected short hardwareType;
-    protected short protocolType;
-    protected byte hardwareAddressLength;
-    protected byte protocolAddressLength;
-    protected short opCode;
-    protected byte[] senderHardwareAddress;
-    protected byte[] senderProtocolAddress;
-    protected byte[] targetHardwareAddress;
-    protected byte[] targetProtocolAddress;
-
-    /**
-     * @return the hardwareType
-     */
-    public short getHardwareType() {
-        return hardwareType;
-    }
-
-    /**
-     * @param hardwareType the hardwareType to set
-     */
-    public ARP setHardwareType(short hardwareType) {
-        this.hardwareType = hardwareType;
-        return this;
-    }
-
-    /**
-     * @return the protocolType
-     */
-    public short getProtocolType() {
-        return protocolType;
-    }
-
-    /**
-     * @param protocolType the protocolType to set
-     */
-    public ARP setProtocolType(short protocolType) {
-        this.protocolType = protocolType;
-        return this;
-    }
-
-    /**
-     * @return the hardwareAddressLength
-     */
-    public byte getHardwareAddressLength() {
-        return hardwareAddressLength;
-    }
-
-    /**
-     * @param hardwareAddressLength the hardwareAddressLength to set
-     */
-    public ARP setHardwareAddressLength(byte hardwareAddressLength) {
-        this.hardwareAddressLength = hardwareAddressLength;
-        return this;
-    }
-
-    /**
-     * @return the protocolAddressLength
-     */
-    public byte getProtocolAddressLength() {
-        return protocolAddressLength;
-    }
-
-    /**
-     * @param protocolAddressLength the protocolAddressLength to set
-     */
-    public ARP setProtocolAddressLength(byte protocolAddressLength) {
-        this.protocolAddressLength = protocolAddressLength;
-        return this;
-    }
-
-    /**
-     * @return the opCode
-     */
-    public short getOpCode() {
-        return opCode;
-    }
-
-    /**
-     * @param opCode the opCode to set
-     */
-    public ARP setOpCode(short opCode) {
-        this.opCode = opCode;
-        return this;
-    }
-
-    /**
-     * @return the senderHardwareAddress
-     */
-    public byte[] getSenderHardwareAddress() {
-        return senderHardwareAddress;
-    }
-
-    /**
-     * @param senderHardwareAddress the senderHardwareAddress to set
-     */
-    public ARP setSenderHardwareAddress(byte[] senderHardwareAddress) {
-        this.senderHardwareAddress = senderHardwareAddress;
-        return this;
-    }
-
-    /**
-     * @return the senderProtocolAddress
-     */
-    public byte[] getSenderProtocolAddress() {
-        return senderProtocolAddress;
-    }
-
-    /**
-     * @param senderProtocolAddress the senderProtocolAddress to set
-     */
-    public ARP setSenderProtocolAddress(byte[] senderProtocolAddress) {
-        this.senderProtocolAddress = senderProtocolAddress;
-        return this;
-    }
-    
-    public ARP setSenderProtocolAddress(int address) {
-        this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
-        return this;
-    }
-
-    /**
-     * @return the targetHardwareAddress
-     */
-    public byte[] getTargetHardwareAddress() {
-        return targetHardwareAddress;
-    }
-
-    /**
-     * @param targetHardwareAddress the targetHardwareAddress to set
-     */
-    public ARP setTargetHardwareAddress(byte[] targetHardwareAddress) {
-        this.targetHardwareAddress = targetHardwareAddress;
-        return this;
-    }
-
-    /**
-     * @return the targetProtocolAddress
-     */
-    public byte[] getTargetProtocolAddress() {
-        return targetProtocolAddress;
-    }
-
-    /**
-     * @return True if gratuitous ARP (SPA = TPA), false otherwise
-     */
-    public boolean isGratuitous() {        
-        assert(senderProtocolAddress.length == targetProtocolAddress.length);
-        
-        int indx = 0;
-        while (indx < senderProtocolAddress.length) {
-            if (senderProtocolAddress[indx] != targetProtocolAddress[indx]) {
-                return false;
-            }
-            indx++;
-        }
-        
-        return true;
-    }
-    
-    /**
-     * @param targetProtocolAddress the targetProtocolAddress to set
-     */
-    public ARP setTargetProtocolAddress(byte[] targetProtocolAddress) {
-        this.targetProtocolAddress = targetProtocolAddress;
-        return this;
-    }
-    
-    public ARP setTargetProtocolAddress(int address) {
-        this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address).array();
-        return this;
-    }
-
-    @Override
-    public byte[] serialize() {
-        int length = 8 + (2 * (0xff & this.hardwareAddressLength))
-                + (2 * (0xff & this.protocolAddressLength));
-        byte[] data = new byte[length];
-        ByteBuffer bb = ByteBuffer.wrap(data);
-        bb.putShort(this.hardwareType);
-        bb.putShort(this.protocolType);
-        bb.put(this.hardwareAddressLength);
-        bb.put(this.protocolAddressLength);
-        bb.putShort(this.opCode);
-        bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
-        bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
-        bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
-        bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
-        return data;
-    }
-
-    @Override
-    public IPacket deserialize(byte[] data, int offset, int length)
-            throws PacketParsingException {
-        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
-        this.hardwareType = bb.getShort();
-        this.protocolType = bb.getShort();
-        this.hardwareAddressLength = bb.get();
-        this.protocolAddressLength = bb.get();
-        if (this.hardwareAddressLength != 6) {
-            String msg = "Incorrect ARP hardware address length: " +
-                        hardwareAddressLength;
-            throw new PacketParsingException(msg);
-        }
-        if (this.protocolAddressLength != 4) {
-            String msg = "Incorrect ARP protocol address length: " +
-                        protocolAddressLength;
-            throw new PacketParsingException(msg);
-        }
-        this.opCode = bb.getShort();
-        this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
-        bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
-        this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
-        bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
-        this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
-        bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
-        this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
-        bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
-        return this;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        final int prime = 13121;
-        int result = super.hashCode();
-        result = prime * result + hardwareAddressLength;
-        result = prime * result + hardwareType;
-        result = prime * result + opCode;
-        result = prime * result + protocolAddressLength;
-        result = prime * result + protocolType;
-        result = prime * result + Arrays.hashCode(senderHardwareAddress);
-        result = prime * result + Arrays.hashCode(senderProtocolAddress);
-        result = prime * result + Arrays.hashCode(targetHardwareAddress);
-        result = prime * result + Arrays.hashCode(targetProtocolAddress);
-        return result;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (!super.equals(obj))
-            return false;
-        if (!(obj instanceof ARP))
-            return false;
-        ARP other = (ARP) obj;
-        if (hardwareAddressLength != other.hardwareAddressLength)
-            return false;
-        if (hardwareType != other.hardwareType)
-            return false;
-        if (opCode != other.opCode)
-            return false;
-        if (protocolAddressLength != other.protocolAddressLength)
-            return false;
-        if (protocolType != other.protocolType)
-            return false;
-        if (!Arrays.equals(senderHardwareAddress, other.senderHardwareAddress))
-            return false;
-        if (!Arrays.equals(senderProtocolAddress, other.senderProtocolAddress))
-            return false;
-        if (!Arrays.equals(targetHardwareAddress, other.targetHardwareAddress))
-            return false;
-        if (!Arrays.equals(targetProtocolAddress, other.targetProtocolAddress))
-            return false;
-        return true;
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#toString()
-     */
-    @Override
-    public String toString() {
-        return "ARP [hardwareType=" + hardwareType + ", protocolType="
-                + protocolType + ", hardwareAddressLength="
-                + hardwareAddressLength + ", protocolAddressLength="
-                + protocolAddressLength + ", opCode=" + opCode
-                + ", senderHardwareAddress="
-                + Arrays.toString(senderHardwareAddress)
-                + ", senderProtocolAddress="
-                + Arrays.toString(senderProtocolAddress)
-                + ", targetHardwareAddress="
-                + Arrays.toString(targetHardwareAddress)
-                + ", targetProtocolAddress="
-                + Arrays.toString(targetProtocolAddress) + "]";
-    }
+	public static short HW_TYPE_ETHERNET = 0x1;
+
+	public static short PROTO_TYPE_IP = 0x800;
+
+	public static ArpOpcode OP_REQUEST = ArpOpcode.REQUEST;
+	public static ArpOpcode OP_REPLY = ArpOpcode.REPLY;
+	public static ArpOpcode OP_RARP_REQUEST = ArpOpcode.REQUEST_REVERSE;
+	public static ArpOpcode OP_RARP_REPLY = ArpOpcode.REPLY_REVERSE;
+
+	protected short hardwareType;
+	protected short protocolType;
+	protected byte hardwareAddressLength;
+	protected byte protocolAddressLength;
+	protected ArpOpcode opCode;
+	protected MacAddress senderHardwareAddress;
+	protected IPv4Address senderProtocolAddress;
+	protected MacAddress targetHardwareAddress;
+	protected IPv4Address targetProtocolAddress;
+
+	/**
+	 * @return the hardwareType
+	 */
+	public short getHardwareType() {
+		return hardwareType;
+	}
+
+	/**
+	 * @param hardwareType the hardwareType to set
+	 */
+	public ARP setHardwareType(short hardwareType) {
+		this.hardwareType = hardwareType;
+		return this;
+	}
+
+	/**
+	 * @return the protocolType
+	 */
+	public short getProtocolType() {
+		return protocolType;
+	}
+
+	/**
+	 * @param protocolType the protocolType to set
+	 */
+	public ARP setProtocolType(short protocolType) {
+		this.protocolType = protocolType;
+		return this;
+	}
+
+	/**
+	 * @return the hardwareAddressLength
+	 */
+	public byte getHardwareAddressLength() {
+		return hardwareAddressLength;
+	}
+
+	/**
+	 * @param hardwareAddressLength the hardwareAddressLength to set
+	 */
+	public ARP setHardwareAddressLength(byte hardwareAddressLength) {
+		this.hardwareAddressLength = hardwareAddressLength;
+		return this;
+	}
+
+	/**
+	 * @return the protocolAddressLength
+	 */
+	public byte getProtocolAddressLength() {
+		return protocolAddressLength;
+	}
+
+	/**
+	 * @param protocolAddressLength the protocolAddressLength to set
+	 */
+	public ARP setProtocolAddressLength(byte protocolAddressLength) {
+		this.protocolAddressLength = protocolAddressLength;
+		return this;
+	}
+
+	/**
+	 * @return the opCode
+	 */
+	public ArpOpcode getOpCode() {
+		return opCode;
+	}
+
+	/**
+	 * @param opCode the opCode to set
+	 */
+	public ARP setOpCode(ArpOpcode opCode) {
+		this.opCode = opCode;
+		return this;
+	}
+
+	/**
+	 * @return the senderHardwareAddress
+	 */
+	public MacAddress getSenderHardwareAddress() {
+		return senderHardwareAddress;
+	}
+
+	/**
+	 * @param senderHardwareAddress the senderHardwareAddress to set
+	 */
+	public ARP setSenderHardwareAddress(MacAddress senderHardwareAddress) {
+		this.senderHardwareAddress = senderHardwareAddress;
+		return this;
+	}
+
+	/**
+	 * @return the senderProtocolAddress
+	 */
+	public IPv4Address getSenderProtocolAddress() {
+		return senderProtocolAddress;
+	}
+
+	/**
+	 * @param senderProtocolAddress the senderProtocolAddress to set
+	 */
+	public ARP setSenderProtocolAddress(IPv4Address senderProtocolAddress) {
+		this.senderProtocolAddress = senderProtocolAddress;
+		return this;
+	}
+
+	/**
+	 * @return the targetHardwareAddress
+	 */
+	public MacAddress getTargetHardwareAddress() {
+		return targetHardwareAddress;
+	}
+
+	/**
+	 * @param targetHardwareAddress the targetHardwareAddress to set
+	 */
+	public ARP setTargetHardwareAddress(MacAddress targetHardwareAddress) {
+		this.targetHardwareAddress = targetHardwareAddress;
+		return this;
+	}
+
+	/**
+	 * @return the targetProtocolAddress
+	 */
+	public IPv4Address getTargetProtocolAddress() {
+		return targetProtocolAddress;
+	}
+
+	/**
+	 * @return True if gratuitous ARP (SPA = TPA), false otherwise
+	 */
+	public boolean isGratuitous() {        
+		assert(senderProtocolAddress.getLength() == targetProtocolAddress.getLength());
+
+		return senderProtocolAddress.equals(targetProtocolAddress);
+	}
+
+	/**
+	 * @param targetProtocolAddress the targetProtocolAddress to set
+	 */
+	public ARP setTargetProtocolAddress(IPv4Address targetProtocolAddress) {
+		this.targetProtocolAddress = targetProtocolAddress;
+		return this;
+	}
+
+	@Override
+	public byte[] serialize() {
+		int length = 8 + (2 * (0xff & this.hardwareAddressLength))
+				+ (2 * (0xff & this.protocolAddressLength));
+		byte[] data = new byte[length];
+		ByteBuffer bb = ByteBuffer.wrap(data);
+		bb.putShort(this.hardwareType);
+		bb.putShort(this.protocolType);
+		bb.put(this.hardwareAddressLength);
+		bb.put(this.protocolAddressLength);
+		bb.putShort((short) this.opCode.getOpcode());
+		bb.put(this.senderHardwareAddress.getBytes());
+		bb.put(this.senderProtocolAddress.getBytes());
+		bb.put(this.targetHardwareAddress.getBytes());
+		bb.put(this.targetProtocolAddress.getBytes());
+		return data;
+	}
+
+	@Override
+	public IPacket deserialize(byte[] data, int offset, int length)
+			throws PacketParsingException {
+		ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
+		this.hardwareType = bb.getShort();
+		this.protocolType = bb.getShort();
+		this.hardwareAddressLength = bb.get();
+		this.protocolAddressLength = bb.get();
+		if (this.hardwareAddressLength != 6) {
+			String msg = "Incorrect ARP hardware address length: " +
+					hardwareAddressLength;
+			throw new PacketParsingException(msg);
+		}
+		if (this.protocolAddressLength != 4) {
+			String msg = "Incorrect ARP protocol address length: " +
+					protocolAddressLength;
+			throw new PacketParsingException(msg);
+		}
+		this.opCode = ArpOpcode.of(bb.getShort());
+
+		byte[] tmpMac = new byte[0xff & this.hardwareAddressLength];
+		byte[] tmpIp = new byte[0xff & this.protocolAddressLength];
+
+		bb.get(tmpMac, 0, this.hardwareAddressLength);
+		this.senderHardwareAddress = MacAddress.of(tmpMac);  
+		bb.get(tmpIp, 0, this.protocolAddressLength);
+		this.senderProtocolAddress = IPv4Address.of(tmpIp);
+
+		bb.get(tmpMac, 0, this.hardwareAddressLength);
+		this.targetHardwareAddress = MacAddress.of(tmpMac);  
+		bb.get(tmpIp, 0, this.protocolAddressLength);
+		this.targetProtocolAddress = IPv4Address.of(tmpIp);
+
+		return this;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + hardwareAddressLength;
+		result = prime * result + hardwareType;
+		result = prime * result + ((opCode == null) ? 0 : opCode.hashCode());
+		result = prime * result + protocolAddressLength;
+		result = prime * result + protocolType;
+		result = prime
+				* result
+				+ ((senderHardwareAddress == null) ? 0 : senderHardwareAddress
+						.hashCode());
+		result = prime
+				* result
+				+ ((senderProtocolAddress == null) ? 0 : senderProtocolAddress
+						.hashCode());
+		result = prime
+				* result
+				+ ((targetHardwareAddress == null) ? 0 : targetHardwareAddress
+						.hashCode());
+		result = prime
+				* result
+				+ ((targetProtocolAddress == null) ? 0 : targetProtocolAddress
+						.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (!super.equals(obj))
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ARP other = (ARP) obj;
+		if (hardwareAddressLength != other.hardwareAddressLength)
+			return false;
+		if (hardwareType != other.hardwareType)
+			return false;
+		if (opCode == null) {
+			if (other.opCode != null)
+				return false;
+		} else if (!opCode.equals(other.opCode))
+			return false;
+		if (protocolAddressLength != other.protocolAddressLength)
+			return false;
+		if (protocolType != other.protocolType)
+			return false;
+		if (senderHardwareAddress == null) {
+			if (other.senderHardwareAddress != null)
+				return false;
+		} else if (!senderHardwareAddress.equals(other.senderHardwareAddress))
+			return false;
+		if (senderProtocolAddress == null) {
+			if (other.senderProtocolAddress != null)
+				return false;
+		} else if (!senderProtocolAddress.equals(other.senderProtocolAddress))
+			return false;
+		if (targetHardwareAddress == null) {
+			if (other.targetHardwareAddress != null)
+				return false;
+		} else if (!targetHardwareAddress.equals(other.targetHardwareAddress))
+			return false;
+		if (targetProtocolAddress == null) {
+			if (other.targetProtocolAddress != null)
+				return false;
+		} else if (!targetProtocolAddress.equals(other.targetProtocolAddress))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ARP [hardwareType=" + hardwareType + ", protocolType="
+				+ protocolType + ", hardwareAddressLength="
+				+ hardwareAddressLength + ", protocolAddressLength="
+				+ protocolAddressLength + ", opCode=" + opCode
+				+ ", senderHardwareAddress=" + senderHardwareAddress
+				+ ", senderProtocolAddress=" + senderProtocolAddress
+				+ ", targetHardwareAddress=" + targetHardwareAddress
+				+ ", targetProtocolAddress=" + targetProtocolAddress + "]";
+	}
+
 }
diff --git a/src/main/java/net/floodlightcontroller/packet/Ethernet.java b/src/main/java/net/floodlightcontroller/packet/Ethernet.java
index 71ef21907..645cb306e 100644
--- a/src/main/java/net/floodlightcontroller/packet/Ethernet.java
+++ b/src/main/java/net/floodlightcontroller/packet/Ethernet.java
@@ -449,9 +449,9 @@ public class Ethernet extends BasePacket {
         if (pkt instanceof ARP) {
             ARP p = (ARP) pkt;
             sb.append("\nnw_src: ");
-            sb.append(IPv4.fromIPv4Address(IPv4.toIPv4Address(p.getSenderProtocolAddress())));
+            sb.append(p.getSenderProtocolAddress().toString());
             sb.append("\nnw_dst: ");
-            sb.append(IPv4.fromIPv4Address(IPv4.toIPv4Address(p.getTargetProtocolAddress())));
+            sb.append(p.getTargetProtocolAddress().toString());
         }
         else if (pkt instanceof LLDP) {
             sb.append("lldp packet");
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index 7e0d2ceac..d0a4a963d 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -46,7 +46,6 @@ import net.floodlightcontroller.debugevent.IDebugEventService;
 import net.floodlightcontroller.packet.ARP;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
 import net.floodlightcontroller.perfmon.PktInProcessingTime;
 import net.floodlightcontroller.restserver.IRestApiService;
@@ -74,6 +73,8 @@ import org.projectfloodlight.openflow.protocol.OFPacketInReason;
 import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.types.DatapathId;
 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.protocol.OFPortDesc;
@@ -180,10 +181,10 @@ public class ControllerTest extends FloodlightTestCase {
                 .setHardwareAddressLength((byte) 6)
                 .setProtocolAddressLength((byte) 4)
                 .setOpCode(ARP.OP_REPLY)
-                .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
-                .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
-                .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+                .setSenderHardwareAddress(MacAddress.of("00:44:33:22:11:00"))
+                .setSenderProtocolAddress(IPv4Address.of("192.168.1.1"))
+                .setTargetHardwareAddress(MacAddress.of("00:11:22:33:44:55"))
+                .setTargetProtocolAddress(IPv4Address.of("192.168.1.2")));
         byte[] testPacketSerialized = testPacket.serialize();
 
         // The specific factory can be obtained from the switch, but we don't have one
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index 525fdcbe8..116e8bb17 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -243,10 +243,10 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
 				.setHardwareAddressLength((byte) 6)
 				.setProtocolAddressLength((byte) 4)
 				.setOpCode(ARP.OP_REPLY)
-				.setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
-				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
-				.setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+				.setSenderHardwareAddress(MacAddress.of("00:44:33:22:11:01"))
+				.setSenderProtocolAddress(IPv4Address.of("192.168.1.1"))
+				.setTargetHardwareAddress(MacAddress.of("00:11:22:33:44:55"))
+				.setTargetProtocolAddress(IPv4Address.of("192.168.1.2")));
 		this.testARPReplyPacket_1_Srld = testARPReplyPacket_1.serialize();
 
 		// Another test packet with the same ARP payload as packet 1 but with
@@ -263,10 +263,10 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
 				.setHardwareAddressLength((byte) 6)
 				.setProtocolAddressLength((byte) 4)
 				.setOpCode(ARP.OP_REPLY)
-				.setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
-				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
-				.setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+				.setSenderHardwareAddress(MacAddress.of("00:44:33:22:11:01"))
+				.setSenderProtocolAddress(IPv4Address.of("192.168.1.1"))
+				.setTargetHardwareAddress(MacAddress.of("00:11:22:33:44:55"))
+				.setTargetProtocolAddress(IPv4Address.of("192.168.1.2")));
 		this.testARPReplyPacket_2_Srld = testARPReplyPacket_2.serialize();
 
 		// This packet reverses the MACs and IP from testARPReplyPacket_1
@@ -1315,7 +1315,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
 	@Test
 	public void testDeviceLearningFromArpResponseData() throws Exception {
 		ARP arp = (ARP)((Ethernet)this.testARPReplyPacket_2).getPayload();
-		MacAddress senderMac = MacAddress.of(arp.getSenderHardwareAddress());
+		MacAddress senderMac = arp.getSenderHardwareAddress();
 		MacAddress sourceMac =
 				((Ethernet)this.testARPReplyPacket_2)
 				.getSourceMACAddress();
@@ -1460,7 +1460,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
 				IDeviceService.CONTEXT_SRC_DEVICE);
 		// yes: we check that cntxSrcDev matched dstMAC because we are
 		// just adding the dest device
-		int ip = IPv4.toIPv4Address("192.168.1.1");
+		int ip = IPv4Address.of("192.168.1.1").getInt();
 		verifyDevice(cntxSrcDev, dstMac.getLong(), (short)5, ip,
 				1L, testARPReplyPacketIn_1.getMatch().get(MatchField.IN_PORT).getShortPortNumber());
 		// yes: we set the expected dst device to the current srcDev
diff --git a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
index 1f5790736..7cc6ef19f 100644
--- a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
+++ b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
@@ -57,6 +57,7 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.protocol.match.MatchField;
 import org.projectfloodlight.openflow.types.DatapathId;
 import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.IPv4Address;
 import org.projectfloodlight.openflow.types.IPv4AddressWithMask;
 import org.projectfloodlight.openflow.types.IpProtocol;
 import org.projectfloodlight.openflow.types.MacAddress;
@@ -151,10 +152,10 @@ public class FirewallTest extends FloodlightTestCase {
                 .setOpCode(ARP.OP_REQUEST)
                 .setHardwareAddressLength((byte)6)
                 .setProtocolAddressLength((byte)4)
-                .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
-                .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
-                .setTargetHardwareAddress(Ethernet.toMACAddress("00:00:00:00:00:00"))
-                .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
+                .setSenderHardwareAddress(MacAddress.of("00:44:33:22:11:00"))
+                .setSenderProtocolAddress(IPv4Address.of("192.168.1.1"))
+                .setTargetHardwareAddress(MacAddress.of("00:00:00:00:00:00"))
+                .setTargetProtocolAddress(IPv4Address.of("192.168.1.2"))
                 .setPayload(new Data(new byte[] {0x01})));
 
         // Build a ARP packet
@@ -170,10 +171,10 @@ public class FirewallTest extends FloodlightTestCase {
                 .setOpCode(ARP.OP_REQUEST)
                 .setHardwareAddressLength((byte)6)
                 .setProtocolAddressLength((byte)4)
-                .setSenderHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
-                .setTargetHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
-                .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
+                .setSenderHardwareAddress(MacAddress.of("00:11:22:33:44:55"))
+                .setSenderProtocolAddress(IPv4Address.of("192.168.1.2"))
+                .setTargetHardwareAddress(MacAddress.of("00:44:33:22:11:00"))
+                .setTargetProtocolAddress(IPv4Address.of("192.168.1.1"))
                 .setPayload(new Data(new byte[] {0x01})));
 
         // Build a broadcast IP packet
diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
index 231db1828..a2640a980 100644
--- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
+++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java
@@ -490,10 +490,10 @@ public class LoadBalancerTest extends FloodlightTestCase {
 				.setHardwareAddressLength((byte) 6)
 				.setProtocolAddressLength((byte) 4)
 				.setOpCode(ARP.OP_REQUEST)
-				.setSenderHardwareAddress(HexString.fromHexString("00:00:00:00:00:01"))
-				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.1"))
-				.setTargetHardwareAddress(HexString.fromHexString("00:00:00:00:00:00"))
-				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.100")));
+				.setSenderHardwareAddress(MacAddress.of("00:00:00:00:00:01"))
+				.setSenderProtocolAddress(IPv4Address.of("10.0.0.1"))
+				.setTargetHardwareAddress(MacAddress.of("00:00:00:00:00:00"))
+				.setTargetProtocolAddress(IPv4Address.of("10.0.0.100")));
 
 		arpRequest1Serialized = arpRequest1.serialize();
 
@@ -522,10 +522,10 @@ public class LoadBalancerTest extends FloodlightTestCase {
 				.setHardwareAddressLength((byte) 6)
 				.setProtocolAddressLength((byte) 4)
 				.setOpCode(ARP.OP_REPLY)
-				.setSenderHardwareAddress(HexString.fromHexString(LBVip.LB_PROXY_MAC))
-				.setSenderProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.100"))
-				.setTargetHardwareAddress(HexString.fromHexString("00:00:00:00:00:01"))
-				.setTargetProtocolAddress(IPv4.toIPv4AddressBytes("10.0.0.1")));
+				.setSenderHardwareAddress(MacAddress.of(LBVip.LB_PROXY_MAC))
+				.setSenderProtocolAddress(IPv4Address.of("10.0.0.100"))
+				.setTargetHardwareAddress(MacAddress.of("00:00:00:00:00:01"))
+				.setTargetProtocolAddress(IPv4Address.of("10.0.0.1")));
 
 		arpReply1Serialized = arpReply1.serialize();
 
diff --git a/src/test/java/net/floodlightcontroller/packet/PacketTest.java b/src/test/java/net/floodlightcontroller/packet/PacketTest.java
index f62f1a8cb..65fafb9dd 100644
--- a/src/test/java/net/floodlightcontroller/packet/PacketTest.java
+++ b/src/test/java/net/floodlightcontroller/packet/PacketTest.java
@@ -18,11 +18,11 @@ package net.floodlightcontroller.packet;
 
 import static org.junit.Assert.*;
 
-import java.util.Arrays;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
 
 public class PacketTest {
     protected IPacket pkt1, pkt2, pkt3, pkt4;
@@ -57,10 +57,10 @@ public class PacketTest {
                     .setHardwareAddressLength((byte) 6)
                     .setProtocolAddressLength((byte) 4)
                     .setOpCode(ARP.OP_REPLY)
-                    .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
-                    .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
-                    .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                    .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+                    .setSenderHardwareAddress(MacAddress.of("00:44:33:22:11:01"))
+                    .setSenderProtocolAddress(IPv4Address.of("192.168.1.1"))
+                    .setTargetHardwareAddress(MacAddress.of("00:11:22:33:44:55"))
+                    .setTargetProtocolAddress(IPv4Address.of("192.168.1.2")));
         
         
         this.pkt3 = new Ethernet()
@@ -74,10 +74,10 @@ public class PacketTest {
                     .setHardwareAddressLength((byte) 6)
                     .setProtocolAddressLength((byte) 4)
                     .setOpCode(ARP.OP_REPLY)
-                    .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:01"))
-                    .setSenderProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.1"))
-                    .setTargetHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                    .setTargetProtocolAddress(IPv4.toIPv4AddressBytes("192.168.1.2")));
+                    .setSenderHardwareAddress(MacAddress.of("00:44:33:22:11:01"))
+                    .setSenderProtocolAddress(IPv4Address.of("192.168.1.1"))
+                    .setTargetHardwareAddress(MacAddress.of("00:11:22:33:44:55"))
+                    .setTargetProtocolAddress(IPv4Address.of("192.168.1.2")));
         
         this.pkt4 = new Ethernet()
         .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
@@ -124,9 +124,8 @@ public class PacketTest {
         if (pkt instanceof ARP) {
             ARP arp = (ARP)pkt;
             ARP newArp = (ARP)newPkt;
-            newArp.setSenderProtocolAddress(new byte[] {1,2,3,4});
-            assertEquals(false, Arrays.equals(newArp.getSenderProtocolAddress(),
-                                              arp.getSenderProtocolAddress()));
+            newArp.setSenderProtocolAddress(IPv4Address.of(new byte[] {1,2,3,4}));
+            assertEquals(false, newArp.getSenderProtocolAddress().equals(arp.getSenderProtocolAddress()));
             assertEquals(false, newPkt.equals(pkt));
         } else {
             byte[] dummyData = dummyPkt.serialize().clone();
-- 
GitLab