diff --git a/src/main/java/net/floodlightcontroller/packet/Ethernet.java b/src/main/java/net/floodlightcontroller/packet/Ethernet.java
index 1e935a63f2d5479f77731e3002333c8971fb2d48..fe74e9e0db5b7dc4fda483108521a985810dcd0e 100644
--- a/src/main/java/net/floodlightcontroller/packet/Ethernet.java
+++ b/src/main/java/net/floodlightcontroller/packet/Ethernet.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
+import net.floodlightcontroller.util.MACAddress;
 import org.openflow.util.HexString;
 
 /**
@@ -29,7 +30,6 @@ import org.openflow.util.HexString;
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
 public class Ethernet extends BasePacket {
-    private static String HEXES = "0123456789ABCDEF";
     public static final short TYPE_ARP = 0x0806;
     public static final short TYPE_IPv4 = 0x0800;
     public static final short TYPE_LLDP = (short) 0x88cc;
@@ -43,8 +43,8 @@ public class Ethernet extends BasePacket {
         etherTypeClassMap.put(TYPE_LLDP, LLDP.class);
     }
 
-    protected byte[] destinationMACAddress;
-    protected byte[] sourceMACAddress;
+    protected MACAddress destinationMACAddress;
+    protected MACAddress sourceMACAddress;
     protected byte priorityCode;
     protected short vlanID;
     protected short etherType;
@@ -62,14 +62,14 @@ public class Ethernet extends BasePacket {
      * @return the destinationMACAddress
      */
     public byte[] getDestinationMACAddress() {
-        return destinationMACAddress;
+        return destinationMACAddress.toBytes();
     }
 
     /**
      * @param destinationMACAddress the destinationMACAddress to set
      */
     public Ethernet setDestinationMACAddress(byte[] destinationMACAddress) {
-        this.destinationMACAddress = destinationMACAddress;
+        this.destinationMACAddress = MACAddress.valueOf(destinationMACAddress);
         return this;
     }
 
@@ -77,8 +77,7 @@ public class Ethernet extends BasePacket {
      * @param destinationMACAddress the destinationMACAddress to set
      */
     public Ethernet setDestinationMACAddress(String destinationMACAddress) {
-        this.destinationMACAddress = Ethernet
-                .toMACAddress(destinationMACAddress);
+        this.destinationMACAddress = MACAddress.valueOf(destinationMACAddress);
         return this;
     }
 
@@ -86,14 +85,14 @@ public class Ethernet extends BasePacket {
      * @return the sourceMACAddress
      */
     public byte[] getSourceMACAddress() {
-        return sourceMACAddress;
+        return sourceMACAddress.toBytes();
     }
 
     /**
      * @param sourceMACAddress the sourceMACAddress to set
      */
     public Ethernet setSourceMACAddress(byte[] sourceMACAddress) {
-        this.sourceMACAddress = sourceMACAddress;
+        this.sourceMACAddress = MACAddress.valueOf(sourceMACAddress);
         return this;
     }
 
@@ -101,7 +100,7 @@ public class Ethernet extends BasePacket {
      * @param sourceMACAddress the sourceMACAddress to set
      */
     public Ethernet setSourceMACAddress(String sourceMACAddress) {
-        this.sourceMACAddress = Ethernet.toMACAddress(sourceMACAddress);
+        this.sourceMACAddress = MACAddress.valueOf(sourceMACAddress);
         return this;
     }
 
@@ -154,22 +153,15 @@ public class Ethernet extends BasePacket {
      * @return True if the Ethernet frame is broadcast, false otherwise
      */
     public boolean isBroadcast() {
-        assert(destinationMACAddress.length == 6);
-        for (byte b : destinationMACAddress) {
-            if (b != -1) // checks if equal to 0xff
-                return false;
-        }
-        return true;
+        assert(destinationMACAddress.length() == 6);
+        return destinationMACAddress.isBroadcast();
     }
     
     /**
      * @return True is the Ethernet frame is multicast, False otherwise
      */
     public boolean isMulticast() {
-        if (this.isBroadcast()) {
-            return false;
-        }
-        return (destinationMACAddress[0] & 0x01) != 0;
+        return destinationMACAddress.isMulticast();
     }
     /**
      * Pad this packet to 60 bytes minimum, filling with zeros?
@@ -201,8 +193,8 @@ public class Ethernet extends BasePacket {
         }
         byte[] data = new byte[length];
         ByteBuffer bb = ByteBuffer.wrap(data);
-        bb.put(destinationMACAddress);
-        bb.put(sourceMACAddress);
+        bb.put(destinationMACAddress.toBytes());
+        bb.put(sourceMACAddress.toBytes());
         if (vlanID != VLAN_UNTAGGED) {
             bb.putShort((short) 0x8100);
             bb.putShort((short) ((priorityCode << 13) | (vlanID & 0x0fff)));
@@ -220,12 +212,16 @@ public class Ethernet extends BasePacket {
     public IPacket deserialize(byte[] data, int offset, int length) {
         ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
         if (this.destinationMACAddress == null)
-            this.destinationMACAddress = new byte[6];
-        bb.get(this.destinationMACAddress);
+            this.destinationMACAddress = MACAddress.valueOf(new byte[6]);
+        byte[] dstAddr = new byte[MACAddress.MAC_ADDRESS_LENGTH];
+        bb.get(dstAddr);
+        this.destinationMACAddress = MACAddress.valueOf(dstAddr);
 
         if (this.sourceMACAddress == null)
-            this.sourceMACAddress = new byte[6];
-        bb.get(this.sourceMACAddress);
+            this.sourceMACAddress = MACAddress.valueOf(new byte[6]);
+        byte[] srcAddr = new byte[MACAddress.MAC_ADDRESS_LENGTH];
+        bb.get(srcAddr);
+        this.sourceMACAddress = MACAddress.valueOf(srcAddr);
 
         short etherType = bb.getShort();
         if (etherType == (short) 0x8100) {
@@ -254,20 +250,6 @@ public class Ethernet extends BasePacket {
         return this;
     }
 
-    public static boolean isMACAddress(String macAddress) {
-        String[] macBytes = macAddress.split(":");
-        if (macBytes.length != 6)
-            return false;
-        for (int i = 0; i < 6; ++i) {
-            if (HEXES.indexOf(macBytes[i].toUpperCase().charAt(0)) == -1 || 
-                HEXES.indexOf(macBytes[i].toUpperCase().charAt(1)) == -1) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-    
     /**
      * Accepts a MAC address of the form 00:aa:11:bb:22:cc, case does not
      * matter, and returns a corresponding byte[].
@@ -275,24 +257,10 @@ public class Ethernet extends BasePacket {
      * @return
      */
     public static byte[] toMACAddress(String macAddress) {
-        byte[] address = new byte[6];
-        
-        if (!Ethernet.isMACAddress(macAddress)) {
-            throw new IllegalArgumentException(
-                    "Specified MAC Address must contain 12 hex digits" +
-                    " separated pairwise by :'s.");
-        }
-        String[] macBytes = macAddress.split(":");
-        for (int i = 0; i < 6; ++i) {
-            address[i] = (byte) ((HEXES.indexOf(macBytes[i].toUpperCase()
-                    .charAt(0)) << 4) | HEXES.indexOf(macBytes[i].toUpperCase()
-                    .charAt(1)));
-        }
-
-        return address;
+        return MACAddress.valueOf(macAddress).toBytes();
     }
 
-    
+
     /**
      * Accepts a MAC address and returns the corresponding long, where the
      * MAC bytes are set on the lower order bytes of the long.
@@ -300,28 +268,16 @@ public class Ethernet extends BasePacket {
      * @return a long containing the mac address bytes
      */
     public static long toLong(byte[] macAddress) {
-        long mac = 0;
-        for (int i = 0; i < 6; i++) {
-          long t = (macAddress[i] & 0xffL) << ((5-i)*8);
-          mac |= t;
-        }
-        return mac;
+        return MACAddress.valueOf(macAddress).toLong();
     }
-    
+
     /**
      * Convert a long MAC address to a byte array
      * @param macAddress
      * @return the bytes of the mac address
      */
     public static byte[] toByteArray(long macAddress) {
-        return new byte[] {
-                (byte)((macAddress >> 40) & 0xff),
-                (byte)((macAddress >> 32) & 0xff),
-                (byte)((macAddress >> 24) & 0xff),
-                (byte)((macAddress >> 16) & 0xff),
-                (byte)((macAddress >> 8 ) & 0xff),
-                (byte)((macAddress >> 0) & 0xff)
-        };
+        return MACAddress.valueOf(macAddress).toBytes();
     }
     
     /* (non-Javadoc)
@@ -331,10 +287,10 @@ public class Ethernet extends BasePacket {
     public int hashCode() {
         final int prime = 7867;
         int result = super.hashCode();
-        result = prime * result + Arrays.hashCode(destinationMACAddress);
+        result = prime * result + destinationMACAddress.hashCode();
         result = prime * result + etherType;
         result = prime * result + (pad ? 1231 : 1237);
-        result = prime * result + Arrays.hashCode(sourceMACAddress);
+        result = prime * result + sourceMACAddress.hashCode();
         return result;
     }
 
@@ -350,7 +306,7 @@ public class Ethernet extends BasePacket {
         if (!(obj instanceof Ethernet))
             return false;
         Ethernet other = (Ethernet) obj;
-        if (!Arrays.equals(destinationMACAddress, other.destinationMACAddress))
+        if (!destinationMACAddress.equals(other.destinationMACAddress))
             return false;
         if (priorityCode != other.priorityCode)
             return false;
@@ -360,7 +316,7 @@ public class Ethernet extends BasePacket {
             return false;
         if (pad != other.pad)
             return false;
-        if (!Arrays.equals(sourceMACAddress, other.sourceMACAddress))
+        if (!sourceMACAddress.equals(other.sourceMACAddress))
             return false;
         return true;
     }
diff --git a/src/main/java/net/floodlightcontroller/util/MACAddress.java b/src/main/java/net/floodlightcontroller/util/MACAddress.java
new file mode 100644
index 0000000000000000000000000000000000000000..f80f110d504b511b8f0b6e3962c985f2ca1be6b3
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/MACAddress.java
@@ -0,0 +1,157 @@
+package net.floodlightcontroller.util;
+
+import java.util.Arrays;
+
+/**
+ * The class representing MAC address.
+ *
+ * @author Sho Shimizu (sho.shimizu@gmail.com)
+ */
+public class MACAddress {
+    public static final int MAC_ADDRESS_LENGTH = 6;
+    private byte[] address = new byte[MAC_ADDRESS_LENGTH];
+
+    private MACAddress(byte[] address) {
+        this.address = Arrays.copyOf(address, MAC_ADDRESS_LENGTH);
+    }
+
+    /**
+     * Returns a MAC address instance representing the value of the specified {@code String}.
+     * @param address the String representation of the MAC Address to be parsed.
+     * @return a MAC Address instance representing the value of the specified {@code String}.
+     * @throws IllegalArgumentException if the string cannot be parsed as a MAC address.
+     */
+    public static MACAddress valueOf(String address) {
+        String[] elements = address.split(":");
+        if (elements.length != MAC_ADDRESS_LENGTH) {
+            throw new IllegalArgumentException(
+                    "Specified MAC Address must contain 12 hex digits" +
+                    " separated pairwise by :'s.");
+        }
+
+        byte[] addressInBytes = new byte[MAC_ADDRESS_LENGTH];
+        for (int i = 0; i < MAC_ADDRESS_LENGTH; i++) {
+            String element = elements[i];
+            addressInBytes[i] = (byte)Integer.parseInt(element, 16);
+        }
+
+        return new MACAddress(addressInBytes);
+    }
+
+    /**
+     * Returns a MAC address instance representing the specified {@code byte} array.
+     * @param address the byte array to be parsed.
+     * @return a MAC address instance representing the specified {@code byte} array.
+     * @throws IllegalArgumentException if the byte array cannot be parsed as a MAC address.
+     */
+    public static MACAddress valueOf(byte[] address) {
+        if (address.length != MAC_ADDRESS_LENGTH) {
+            throw new IllegalArgumentException("the length is not " + MAC_ADDRESS_LENGTH);
+        }
+
+        return new MACAddress(address);
+    }
+
+    /**
+     * Returns a MAC address instance representing the specified {@code long} value.
+     * The lower 48 bits of the long value are used to parse as a MAC address.
+     * @param address the long value to be parsed. The lower 48 bits are used for a MAC address.
+     * @return a MAC address instance representing the specified {@code long} value.
+     * @throws IllegalArgumentException if the long value cannot be parsed as a MAC address.
+     */
+    public static MACAddress valueOf(long address) {
+        byte[] addressInBytes = new byte[] {
+                (byte)((address >> 40) & 0xff),
+                (byte)((address >> 32) & 0xff),
+                (byte)((address >> 24) & 0xff),
+                (byte)((address >> 16) & 0xff),
+                (byte)((address >> 8 ) & 0xff),
+                (byte)((address >> 0) & 0xff)
+        };
+
+        return new MACAddress(addressInBytes);
+    }
+
+    /**
+     * Returns the length of the {@code MACAddress}.
+     * @return the length of the {@code MACAddress}.
+     */
+    public int length() {
+        return address.length;
+    }
+
+    /**
+     * Returns the value of the {@code MACAddress} as a {@code byte} array.
+     * @return the numeric value represented by this object after conversion to type {@code byte} array.
+     */
+    public byte[] toBytes() {
+        return Arrays.copyOf(address, address.length);
+    }
+
+    /**
+     * Returns the value of the {@code MACAddress} as a {@code long}.
+     * @return the numeric value represented by this object after conversion to type {@code long}.
+     */
+    public long toLong() {
+        long mac = 0;
+        for (int i = 0; i < 6; i++) {
+            long t = (address[i] & 0xffL) << ((5 - i) * 8);
+            mac |= t;
+        }
+        return mac;
+    }
+
+    /**
+     * Returns {@code true} if the MAC address is the broadcast address.
+     * @return {@code true} if the MAC address is the broadcast address.
+     */
+    public boolean isBroadcast() {
+        for (byte b : address) {
+            if (b != -1) // checks if equal to 0xff
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns {@code true} if the MAC address is the multicast address.
+     * @return {@code true} if the MAC address is the multicast address.
+     */
+    public boolean isMulticast() {
+        if (isBroadcast()) {
+            return false;
+        }
+        return (address[0] & 0x01) != 0;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof MACAddress)) {
+            return false;
+        }
+
+        MACAddress other = (MACAddress)o;
+        return Arrays.equals(this.address, other.address);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(this.address);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        for (byte b: address) {
+            if (builder.length() > 0) {
+                builder.append(":");
+            }
+            builder.append(String.format("%02X", b & 0xFF));
+        }
+        return builder.toString();
+    }
+}
diff --git a/src/test/java/net/floodlightcontroller/util/MACAddressTest.java b/src/test/java/net/floodlightcontroller/util/MACAddressTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..158f321d0bbbad1684d51a59c2ece8798ff51068
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/util/MACAddressTest.java
@@ -0,0 +1,85 @@
+package net.floodlightcontroller.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * @author Sho Shimizu (sho.shimizu@gmail.com)
+ */
+public class MACAddressTest {
+    @Test
+    public void testValueOf() {
+        MACAddress address = MACAddress.valueOf("00:01:02:03:04:05");
+        assertEquals(address,
+                MACAddress.valueOf(new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}));
+        assertEquals("00:01:02:03:04:05", address.toString());
+
+        address = MACAddress.valueOf("FF:FE:FD:10:20:30");
+        assertEquals(address,
+                MACAddress.valueOf(new byte[]{(byte) 0xFF, (byte) 0xFE, (byte) 0xFD, 0x10, 0x20, 0x30}));
+        assertEquals("FF:FE:FD:10:20:30", address.toString());
+        
+        address = MACAddress.valueOf("00:11:22:aa:bb:cc");
+        assertEquals(address,
+                MACAddress.valueOf(new byte[]{0x00, 0x11, 0x22, (byte)0xaa, (byte)0xbb, (byte)0xcc}));
+    }
+
+    @Test(expected=NumberFormatException.class)
+    public void testIllegalFormat() {
+        MACAddress address = MACAddress.valueOf("0T:00:01:02:03:04");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testLongStringFields() {
+        MACAddress address = MACAddress.valueOf("00:01:02:03:04:05:06");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testShortStringFields() {
+        MACAddress address = MACAddress.valueOf("00:01:02:03:04");
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testLongByteFields() {
+        MACAddress address = MACAddress.valueOf(new byte[]{0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06});
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testShortByteField() {
+        MACAddress address = MACAddress.valueOf(new byte[]{0x01, 0x01, 0x02, 0x03, 0x04});
+    }
+
+    //  Test data is imported from net.floodlightcontroller.packet.EthernetTest
+    @Test
+    public void testToLong() {
+        assertEquals(
+                281474976710655L,
+                MACAddress.valueOf(new byte[]{(byte) 0xff, (byte) 0xff,
+                        (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}).toLong());
+
+        assertEquals(
+                1103823438081L,
+                MACAddress.valueOf(new byte[] { (byte) 0x01, (byte) 0x01,
+                        (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01 }).toLong());
+
+        assertEquals(
+                141289400074368L,
+                MACAddress.valueOf(new byte[] { (byte) 0x80, (byte) 0x80,
+                        (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80 }).toLong());
+
+    }
+    
+    @Test
+    public void testIsBroadcast() {
+        assertTrue(MACAddress.valueOf("FF:FF:FF:FF:FF:FF").isBroadcast());
+        assertFalse(MACAddress.valueOf("11:22:33:44:55:66").isBroadcast());
+    }
+
+    @Test
+    public void testIsMulticast() {
+        assertTrue(MACAddress.valueOf("01:80:C2:00:00:00").isMulticast());
+        assertFalse(MACAddress.valueOf("FF:FF:FF:FF:FF:FF").isMulticast());
+        assertFalse(MACAddress.valueOf("11:22:33:44:55:66").isBroadcast());
+    }
+}