adding EthType to secure handling ether types

this will also pretty print ethertypes in flow output

Change-Id: I9363070ad308f3c756735e29b3992c500e503636
diff --git a/utils/misc/src/main/java/org/onlab/packet/EthType.java b/utils/misc/src/main/java/org/onlab/packet/EthType.java
new file mode 100644
index 0000000..4f52b7d
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/packet/EthType.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onlab.packet;
+
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+
+/**
+ * Representation of an Ethertype.
+ */
+public class EthType {
+
+    public static final short ARP = EtherType.ARP.ethType.toShort();
+    public static final short RARP = EtherType.RARP.ethType.toShort();
+    public static final short VLAN = EtherType.VLAN.ethType.toShort();
+    public static final short IPV4 = EtherType.IPV4.ethType.toShort();
+    public static final short IPV6 = EtherType.IPV6.ethType.toShort();
+    public static final short LLDP = EtherType.LLDP.ethType.toShort();
+    public static final short BDDP = EtherType.BDDP.ethType.toShort();
+    public static final short MPLS_MULTICAST = EtherType.MPLS_UNICAST.ethType.toShort();
+    public static final short MPLS_UNICAST = EtherType.MPLS_UNICAST.ethType.toShort();
+
+    private short etherType;
+
+    /*
+     * Reverse-lookup map for getting a EtherType enum
+     */
+    private static final Map<Short, EtherType> LOOKUP = Maps.newHashMap();
+
+    static {
+        for (EtherType eth : EtherType.values()) {
+            LOOKUP.put(eth.ethType().toShort(), eth);
+        }
+    }
+
+    public EthType(int etherType) {
+        this.etherType = (short) (etherType & 0xFFFF);
+    }
+
+    public EthType(short etherType) {
+        this.etherType = etherType;
+    }
+
+    public short toShort() {
+        return etherType;
+    }
+
+    public static EtherType lookup(short etherType) {
+        return LOOKUP.get(etherType);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        EthType ethType = (EthType) o;
+
+        if (etherType != ethType.etherType) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) etherType;
+    }
+
+    public String toString() {
+        EtherType ethType = lookup(this.etherType);
+        return (ethType == null ? "unknown" : ethType.toString());
+    }
+
+    public static enum EtherType {
+
+        ARP(0x806, "arp", ARP.class),
+        RARP(0x8035, "rarp", null),
+        IPV4(0x800, "ipv4", IPv4.class),
+        IPV6(0x86dd, "ipv6", IPv6.class),
+        LLDP(0x88cc, "lldp", LLDP.class),
+        VLAN(0x8100, "vlan", null),
+        BDDP(0x8942, "bddp", LLDP.class),
+        MPLS_UNICAST(0x8847, "mpls_unicast", null),
+        MPLS_MULTICAST(0x8848, "mpls_unicast", null);
+
+
+        private final Class clazz;
+        private EthType ethType;
+        private String type;
+
+        EtherType(int ethType, String type, Class clazz) {
+            this.ethType = new EthType(ethType);
+            this.type = type;
+            this.clazz = clazz;
+        }
+
+        public EthType ethType() {
+            return ethType;
+        }
+
+        @Override
+        public String toString() {
+            return type;
+        }
+
+        public Class clazz() {
+            return clazz;
+        }
+
+
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/Ethernet.java b/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
index 714266e..779d96c 100644
--- a/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
+++ b/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
@@ -31,28 +31,28 @@
  */
 public class Ethernet extends BasePacket {
     private static final String HEXES = "0123456789ABCDEF";
-    public static final short TYPE_ARP = (short) 0x0806;
-    public static final short TYPE_RARP = (short) 0x8035;
-    public static final short TYPE_IPV4 = (short) 0x0800;
-    public static final short TYPE_IPV6 = (short) 0x86dd;
-    public static final short TYPE_LLDP = (short) 0x88cc;
-    public static final short TYPE_VLAN = (short) 0x8100;
-    public static final short TYPE_BSN = (short) 0x8942;
-    public static final short VLAN_UNTAGGED = (short) 0xffff;
-    public static final short MPLS_UNICAST = (short) 0x8847;
-    public static final short MPLS_MULTICAST = (short) 0x8848;
+    public static final short TYPE_ARP = EthType.ARP;
+    public static final short TYPE_RARP = EthType.RARP;
+    public static final short TYPE_IPV4 = EthType.IPV4;
+    public static final short TYPE_IPV6 = EthType.IPV6;
+    public static final short TYPE_LLDP = EthType.LLDP;
+    public static final short TYPE_VLAN = EthType.VLAN;
+    public static final short TYPE_BSN = EthType.BDDP;
 
+    public static final short MPLS_UNICAST = EthType.MPLS_UNICAST;
+    public static final short MPLS_MULTICAST = EthType.MPLS_MULTICAST;
+
+    public static final short VLAN_UNTAGGED = (short) 0xffff;
     public static final short DATALAYER_ADDRESS_LENGTH = 6; // bytes
     public static final Map<Short, Class<? extends IPacket>> ETHER_TYPE_CLASS_MAP =
         new HashMap<>();
 
     static {
-        Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_ARP, ARP.class);
-        Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_RARP, ARP.class);
-        Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_IPV4, IPv4.class);
-        Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_IPV6, IPv6.class);
-        Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_LLDP, LLDP.class);
-        Ethernet.ETHER_TYPE_CLASS_MAP.put(Ethernet.TYPE_BSN, LLDP.class);
+       for (EthType.EtherType ethType : EthType.EtherType.values()) {
+           if (ethType.clazz() != null) {
+               ETHER_TYPE_CLASS_MAP.put(ethType.ethType().toShort(), ethType.clazz());
+           }
+       }
     }
 
     protected MacAddress destinationMACAddress;