diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py
index 26f7871c75975fb036c18f7571f9fd0ab35cd09b..25eed3dcdbb9aaa65871492b564a2a120cc207a6 100644
--- a/scapy/layers/l2.py
+++ b/scapy/layers/l2.py
@@ -262,65 +262,265 @@ class STP(Packet):
                     BCDFloatField("fwddelay", 15) ]
 
 
+
+#
+# EAPOL
+#
+
+#________________________________________________________________________
+#
+# EAPOL protocol version
+# IEEE Std 802.1X-2010 - Section 11.3.1
+#________________________________________________________________________
+#
+
+eapol_versions = {
+    0x1: "802.1X-2001",
+    0x2: "802.1X-2004",
+    0x3: "802.1X-2010",
+}
+
+#________________________________________________________________________
+#
+# EAPOL Packet Types
+# IEEE Std 802.1X-2010 - Table 11.3
+#________________________________________________________________________
+#
+
+eapol_types = {
+    0x0: "EAP-Packet",  # "EAPOL-EAP" in 801.1X-2010
+    0x1: "EAPOL-Start",
+    0x2: "EAPOL-Logoff",
+    0x3: "EAPOL-Key",
+    0x4: "EAPOL-Encapsulated-ASF-Alert",
+    0x5: "EAPOL-MKA",
+    0x6: "EAPOL-Announcement (Generic)",
+    0x7: "EAPOL-Announcement (Specific)",
+    0x8: "EAPOL-Announcement-Req"
+}
+
+
 class EAPOL(Packet):
+
+    """
+    EAPOL - IEEE Std 802.1X-2010
+    """
+
     name = "EAPOL"
-    fields_desc = [ ByteField("version", 1),
-                    ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]),
-                    LenField("len", None, "H") ]
-    
-    EAP_PACKET= 0
+    fields_desc = [
+        ByteEnumField("version", 1, eapol_versions),
+        ByteEnumField("type", 0, eapol_types),
+        LenField("len", None, "H")
+    ]
+
+    EAP_PACKET = 0
     START = 1
     LOGOFF = 2
     KEY = 3
     ASF = 4
+
     def extract_padding(self, s):
         l = self.len
-        return s[:l],s[l:]
+        return s[:l], s[l:]
+
     def hashret(self):
-        return chr(self.type)+self.payload.hashret()
+        return chr(self.type) + self.payload.hashret()
+
     def answers(self, other):
-        if isinstance(other,EAPOL):
-            if ( (self.type == self.EAP_PACKET) and
-                 (other.type == self.EAP_PACKET) ):
+        if isinstance(other, EAPOL):
+            if ((self.type == self.EAP_PACKET) and
+               (other.type == self.EAP_PACKET)):
                 return self.payload.answers(other.payload)
         return 0
+
     def mysummary(self):
         return self.sprintf("EAPOL %EAPOL.type%")
-             
+
+
+#
+# EAP
+#
+
+
+#________________________________________________________________________
+#
+# EAP methods types
+# http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml#eap-numbers-4
+#________________________________________________________________________
+#
+
+eap_types = {
+    0:   "Reserved",
+    1:   "Identity",
+    2:   "Notification",
+    3:   "Legacy Nak",
+    4:   "MD5-Challenge",
+    5:   "One-Time Password (OTP)",
+    6:   "Generic Token Card (GTC)",
+    7:   "Allocated - RFC3748",
+    8:   "Allocated - RFC3748",
+    9:   "RSA Public Key Authentication",
+    10:  "DSS Unilateral",
+    11:  "KEA",
+    12:  "KEA-VALIDATE",
+    13:  "EAP-TLS",
+    14:  "Defender Token (AXENT)",
+    15:  "RSA Security SecurID EAP",
+    16:  "Arcot Systems EAP",
+    17:  "EAP-Cisco Wireless",
+    18:  "GSM Subscriber Identity Modules (EAP-SIM)",
+    19:  "SRP-SHA1",
+    20:  "Unassigned",
+    21:  "EAP-TTLS",
+    22:  "Remote Access Service",
+    23:  "EAP-AKA Authentication",
+    24:  "EAP-3Com Wireless",
+    25:  "PEAP",
+    26:  "MS-EAP-Authentication",
+    27:  "Mutual Authentication w/Key Exchange (MAKE)",
+    28:  "CRYPTOCard",
+    29:  "EAP-MSCHAP-V2",
+    30:  "DynamID",
+    31:  "Rob EAP",
+    32:  "Protected One-Time Password",
+    33:  "MS-Authentication-TLV",
+    34:  "SentriNET",
+    35:  "EAP-Actiontec Wireless",
+    36:  "Cogent Systems Biometrics Authentication EAP",
+    37:  "AirFortress EAP",
+    38:  "EAP-HTTP Digest",
+    39:  "SecureSuite EAP",
+    40:  "DeviceConnect EAP",
+    41:  "EAP-SPEKE",
+    42:  "EAP-MOBAC",
+    43:  "EAP-FAST",
+    44:  "ZoneLabs EAP (ZLXEAP)",
+    45:  "EAP-Link",
+    46:  "EAP-PAX",
+    47:  "EAP-PSK",
+    48:  "EAP-SAKE",
+    49:  "EAP-IKEv2",
+    50:  "EAP-AKA",
+    51:  "EAP-GPSK",
+    52:  "EAP-pwd",
+    53:  "EAP-EKE Version 1",
+    54:  "EAP Method Type for PT-EAP",
+    55:  "TEAP",
+    254: "Reserved for the Expanded Type",
+    255: "Experimental",
+}
+
+
+#________________________________________________________________________
+#
+# EAP codes
+# http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml#eap-numbers-1
+#________________________________________________________________________
+#
+
+eap_codes = {
+    1: "Request",
+    2: "Response",
+    3: "Success",
+    4: "Failure",
+    5: "Initiate",
+    6: "Finish"
+}
+
 
 class EAP(Packet):
+
+    """
+    RFC 3748 - Extensible Authentication Protocol (EAP)
+    """
+
     name = "EAP"
-    fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}),
-                    ByteField("id", 0),
-                    ShortField("len",None),
-                    ConditionalField(ByteEnumField("type",0, {1:"ID",4:"MD5"}), lambda pkt:pkt.code not in [EAP.SUCCESS, EAP.FAILURE])
+    fields_desc = [
+        ByteEnumField("code", 4, eap_codes),
+        ByteField("id", 0),
+        ShortField("len", None),
+        ConditionalField(ByteEnumField("type", 0, eap_types),
+                         lambda pkt:pkt.code not in [
+                             EAP.SUCCESS, EAP.FAILURE]),
+        ConditionalField(ByteEnumField("desired_auth_type", 0, eap_types),
+                         lambda pkt:pkt.code == EAP.RESPONSE and pkt.type == 3),
+        ConditionalField(
+            StrLenField("identity", '', length_from=lambda pkt: pkt.len - 5),
+                         lambda pkt: pkt.code == EAP.RESPONSE and hasattr(pkt, 'type') and pkt.type == 1)
+    ]
+
+    #________________________________________________________________________
+    #
+    # EAP codes
+    # http://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml#eap-numbers-1
+    #________________________________________________________________________
+    #
 
-                                     ]
-    
     REQUEST = 1
     RESPONSE = 2
     SUCCESS = 3
     FAILURE = 4
-    TYPE_ID = 1
-    TYPE_MD5 = 4
+    INITIATE = 5
+    FINISH = 6
+
     def answers(self, other):
-        if isinstance(other,EAP):
+        if isinstance(other, EAP):
             if self.code == self.REQUEST:
                 return 0
             elif self.code == self.RESPONSE:
-                if ( (other.code == self.REQUEST) and
-                     (other.type == self.type) ):
+                if ((other.code == self.REQUEST) and
+                   (other.type == self.type)):
                     return 1
             elif other.code == self.RESPONSE:
                 return 1
         return 0
-    
+
     def post_build(self, p, pay):
         if self.len is None:
-            l = len(p)+len(pay)
-            p = p[:2]+chr((l>>8)&0xff)+chr(l&0xff)+p[4:]
-        return p+pay
-             
+            l = len(p) + len(pay)
+            p = p[:2] + chr((l >> 8) & 0xff) + chr(l & 0xff) + p[4:]
+        return p + pay
+
+
+class EAP_TLS(Packet):
+
+    """
+    RFC 5216 - "The EAP-TLS Authentication Protocol"
+    """
+
+    name = "EAP-TLS"
+    fields_desc = [
+        BitField('L', 0, 1),
+        BitField('M', 0, 1),
+        BitField('S', 0, 1),
+        BitField('reserved', 0, 5),
+        ConditionalField(
+            IntField('tls_message_len', 0), lambda pkt: pkt.L == 1),
+        ConditionalField(
+            StrLenField('tls_data', '', length_from=lambda pkt: pkt.tls_message_len), lambda pkt: pkt.L == 1)
+    ]
+
+
+class EAP_FAST(Packet):
+
+    """
+    RFC 4851 - "The Flexible Authentication via Secure Tunneling
+    Extensible Authentication Protocol Method (EAP-FAST)"
+    """
+
+    name = "EAP-FAST"
+    fields_desc = [
+        BitField('L', 0, 1),
+        BitField('M', 0, 1),
+        BitField('S', 0, 1),
+        BitField('reserved', 0, 2),
+        BitField('version', 0, 3),
+        ConditionalField(IntField('message_len', 0), lambda pkt: pkt.L == 1),
+        ConditionalField(
+            StrLenField('data', '', length_from=lambda pkt: pkt.message_len), lambda pkt: pkt.L == 1)
+    ]
+
+
 
 class ARP(Packet):
     name = "ARP"
@@ -416,6 +616,8 @@ bind_layers( GRE,           GRErouting,    { "routing_present" : 1 } )
 bind_layers( GRErouting,    conf.raw_layer,{ "address_family" : 0, "SRE_len" : 0 })
 bind_layers( GRErouting,    GRErouting,    { } )
 bind_layers( EAPOL,         EAP,           type=0)
+bind_layers(EAP,           EAP_TLS,       type=13)
+bind_layers(EAP,           EAP_FAST,      type=43)
 bind_layers( LLC,           STP,           dsap=66, ssap=66, ctrl=3)
 bind_layers( LLC,           SNAP,          dsap=170, ssap=170, ctrl=3)
 bind_layers( SNAP,          Dot1Q,         code=33024)
diff --git a/test/regression.uts b/test/regression.uts
index baee093ae1ad4cff7e4e77a70ba0489d10a44110..05a94c2a0a5d6ac813d1d5b6d6b538c9362c9be7 100644
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -4850,3 +4850,150 @@ ff02::%lo0/32                      ::1                            UC          -
     assert(check_mandatory_ipv6_routes(routes))
 
 test_netbsd_7_0()
+
+
+############
+############
+
+########### EAPOL Class ######################################
++ EAPOL class test
+
+= EAPOL - Basic Instantiation
+str(EAPOL()) == '\x01\x00\x00\x00'
+
+= EAPOL - Instantiation with specific values
+str(EAPOL(version = 3, type = 5)) == '\x03\x05\x00\x00'
+
+= EAPOL - Dissection (1)
+s = '\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+eapol = EAPOL(s)
+eapol.version == 3
+eapol.type == 1
+eapol.len = 0
+
+= EAPOL - Dissection (2)
+s = '\x03\x00\x00\x05\x01\x01\x00\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+eapol = EAPOL(s)
+eapol.version == 3
+eapol.type == 0
+eapol.len == 5
+
+= EAPOL - Dissection (3)
+s = '\x03\x00\x00\x0e\x02\x01\x00\x0e\x01anonymous\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+eapol = EAPOL(s)
+eapol.version == 3
+eapol.type == 0
+eapol.len == 14
+
+= EAPOL - Dissection (4)
+req = EAPOL('\x03\x00\x00\x05\x01\x01\x00\x05\x01')
+ans = EAPOL('\x03\x00\x00\x0e\x02\x01\x00\x0e\x01anonymous')
+ans.answers(req)
+
+= EAPOL - Dissection (5)
+s = '\x02\x00\x00\x06\x01\x01\x00\x06\r '
+eapol = EAPOL(s)
+eapol.version == 2
+eapol.type == 0
+eapol.len == 6
+eapol.haslayer(EAP_TLS)
+
+= EAPOL - Dissection (6)
+s = '\x03\x00\x00<\x02\x9e\x00<+\x01\x16\x03\x01\x001\x01\x00\x00-\x03\x01dr1\x93ZS\x0en\xad\x1f\xbaH\xbb\xfe6\xe6\xd0\xcb\xec\xd7\xc0\xd7\xb9\xa5\xc9\x0c\xfd\x98o\xa7T \x00\x00\x04\x004\x00\x00\x01\x00\x00\x00'
+eapol = EAPOL(s)
+eapol.version == 3
+eapol.type == 0
+eapol.len == 60
+eapol.haslayer(EAP_FAST)
+
+
+
+########## EAP Class ######################################
++ EAP class test
+
+= EAP - Basic Instantiation
+str(EAP()) == '\x04\x00\x00\x04'
+
+= EAP - Instantiation with specific values
+str(EAP(code = 1, id = 1, len = 5, type = 1)) == '\x01\x01\x00\x05\x01'
+
+= EAP - Dissection (1)
+s = '\x01\x01\x00\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+eap = EAP(s)
+eap.code == 1
+eap.id == 1
+eap.len == 5
+hasattr(eap, "type")
+eap.type == 1
+
+= EAP - Dissection (2)
+s = '\x02\x01\x00\x0e\x01anonymous\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+eap = EAP(s)
+eap.code == 2
+eap.id == 1
+eap.len == 14
+eap.type == 1
+hasattr(eap, 'identity')
+eap.identity == 'anonymous'
+
+= EAP - Dissection (3)
+s = '\x01\x01\x00\x06\r '
+eap = EAP(s)
+eap.code == 1
+eap.id == 1
+eap.len == 6
+eap.type == 13
+eap.haslayer(EAP_TLS)
+eap[EAP_TLS].L == 0
+eap[EAP_TLS].M == 0
+eap[EAP_TLS].S == 1
+
+= EAP - Dissection (4)
+s = '\x02\x01\x00\xd1\r\x00\x16\x03\x01\x00\xc6\x01\x00\x00\xc2\x03\x01UK\x02\xdf\x1e\xde5\xab\xfa[\x15\xef\xbe\xa2\xe4`\xc6g\xb9\xa8\xaa%vAs\xb2\x1cXt\x1c0\xb7\x00\x00P\xc0\x14\xc0\n\x009\x008\x00\x88\x00\x87\xc0\x0f\xc0\x05\x005\x00\x84\xc0\x12\xc0\x08\x00\x16\x00\x13\xc0\r\xc0\x03\x00\n\xc0\x13\xc0\t\x003\x002\x00\x9a\x00\x99\x00E\x00D\xc0\x0e\xc0\x04\x00/\x00\x96\x00A\xc0\x11\xc0\x07\xc0\x0c\xc0\x02\x00\x05\x00\x04\x00\x15\x00\x12\x00\t\x00\xff\x01\x00\x00I\x00\x0b\x00\x04\x03\x00\x01\x02\x00\n\x004\x002\x00\x0e\x00\r\x00\x19\x00\x0b\x00\x0c\x00\x18\x00\t\x00\n\x00\x16\x00\x17\x00\x08\x00\x06\x00\x07\x00\x14\x00\x15\x00\x04\x00\x05\x00\x12\x00\x13\x00\x01\x00\x02\x00\x03\x00\x0f\x00\x10\x00\x11\x00#\x00\x00\x00\x0f\x00\x01\x01'
+eap = EAP(s)
+eap.code == 2
+eap.id == 1
+eap.len == 209
+eap.type == 13
+eap.haslayer(EAP_TLS)
+eap[EAP_TLS].L == 0
+eap[EAP_TLS].M == 0
+eap[EAP_TLS].S == 0
+
+= EAP - Dissection (5)
+s = '\x02\x9e\x00<+\x01\x16\x03\x01\x001\x01\x00\x00-\x03\x01dr1\x93ZS\x0en\xad\x1f\xbaH\xbb\xfe6\xe6\xd0\xcb\xec\xd7\xc0\xd7\xb9\xa5\xc9\x0c\xfd\x98o\xa7T \x00\x00\x04\x004\x00\x00\x01\x00\x00\x00'
+eap = EAP(s)
+eap.code == 2
+eap.id == 158
+eap.len == 60
+eap.type == 43
+eap.haslayer(EAP_FAST)
+eap[EAP_FAST].L == 0
+eap[EAP_FAST].M == 0
+eap[EAP_FAST].S == 0
+eap[EAP_FAST].version == 1
+
+= EAP - Dissection (6)
+s = '\x02\x9f\x01L+\x01\x16\x03\x01\x01\x06\x10\x00\x01\x02\x01\x00Y\xc9\x8a\tcw\t\xdcbU\xfd\x035\xcd\x1a\t\x10f&[(9\xf6\x88W`\xc6\x0f\xb3\x84\x15\x19\xf5\tk\xbd\x8fp&0\xb0\xa4B\x85\x0c<:s\xf2zT\xc3\xbd\x8a\xe4D{m\xe7\x97\xfe>\xda\x14\xb8T1{\xd7H\x9c\xa6\xcb\xe3,u\xdf\xe0\x82\xe5R\x1e<\xe5\x03}\xeb\x98\xe2\xf7\x8d3\xc6\x83\xac"\x8f\xd7\x12\xe5{:"\x84A\xd9\x14\xc2cZF\xd4\t\xab\xdar\xc7\xe0\x0e\x00o\xce\x05g\xdc?\xcc\xf7\xe83\x83E\xb3>\xe8<3-QB\xfd$C/\x1be\xcf\x03\xd6Q4\xbe\\h\xba)<\x99N\x89\xd9\xb1\xfa!\xd7a\xef\xa3\xd3o\xed8Uz\xb5k\xb0`\xfeC\xbc\xb3aS,d\xe6\xdc\x13\xa4A\x1e\x9b\r{\xd6s \xd0cQ\x95y\xc8\x1d\xc3\xd9\x87\xf2=\x81\x96q~\x99E\xc3\x97\xa8px\xe2\xc7\x92\xeb\xff/v\x84\x1e\xfb\x00\x95#\xba\xfb\xd88h\x90K\xa7\xbd9d\xb4\xf2\xf2\x14\x02vtW\xaa\xadY\x14\x03\x01\x00\x01\x01\x16\x03\x01\x000\x97\xc5l\xd6\xef\xffcM\x81\x90Q\x96\xf6\xfeX1\xf7\xfc\x84\xc6\xa0\xf6Z\xcd\xb6\xe1\xd4\xdb\x88\xf9t%Q!\xe7,~#2G-\xdf\x83\xbf\x86Q\xa2$'
+eap = EAP(s)
+eap.code == 2
+eap.id == 159
+eap.len == 332
+eap.type == 43
+eap.haslayer(EAP_FAST)
+eap[EAP_FAST].L == 0
+eap[EAP_FAST].M == 0
+eap[EAP_FAST].S == 0
+eap[EAP_FAST].version == 1
+
+= EAP - Dissection (7)
+s = '\x02\xf1\x00\x06\x03+'
+eap = EAP(s)
+eap.code == 2
+eap.id == 241
+eap.len == 6
+eap.type == 3
+hasattr(eap, 'desired_auth_type')
+eap.desired_auth_type == 43
+
+