From 025621b7c6580ce1f9a7e6063e0a37317c88de39 Mon Sep 17 00:00:00 2001
From: Pierre Lorinquer <pierre.lorinquer@ssi.gouv.fr>
Date: Tue, 11 Jul 2017 14:30:46 +0200
Subject: [PATCH] "EAP-related" code has been put in a separate module.

---
 scapy/config.py        |   2 +-
 scapy/layers/eap.py    | 729 +++++++++++++++++++++++++++++++++++++++++
 scapy/layers/l2.py     | 710 +--------------------------------------
 scapy/layers/radius.py |   2 +-
 4 files changed, 732 insertions(+), 711 deletions(-)
 create mode 100644 scapy/layers/eap.py

diff --git a/scapy/config.py b/scapy/config.py
index 3e73b7e6..b0f54d4c 100755
--- a/scapy/config.py
+++ b/scapy/config.py
@@ -436,7 +436,7 @@ debug_tls:When 1, print some TLS session secrets when they are computed.
                    "mobileip", "netbios", "netflow", "ntp", "ppp", "pptp",
                    "radius", "rip", "rtp", "skinny", "smb", "snmp",
                    "tftp", "x509", "bluetooth", "dhcp6", "llmnr",
-                   "sctp", "vrrp", "ipsec", "lltd", "vxlan"]
+                   "sctp", "vrrp", "ipsec", "lltd", "vxlan", "eap"]
     contribs = dict()
     crypto_valid = isCryptographyValid()
     crypto_valid_advanced = isCryptographyAdvanced()
diff --git a/scapy/layers/eap.py b/scapy/layers/eap.py
new file mode 100644
index 00000000..172b2a67
--- /dev/null
+++ b/scapy/layers/eap.py
@@ -0,0 +1,729 @@
+## This file is part of Scapy
+## See http://www.secdev.org/projects/scapy for more informations
+## Copyright (C) Philippe Biondi <phil@secdev.org>
+## This program is published under a GPLv2 license
+
+"""
+Classes related to the EAP protocol.
+"""
+
+from __future__ import absolute_import
+from __future__ import print_function
+
+from scapy.fields import BitField, ByteField, XByteField, ByteEnumField,\
+ShortField, IntField, XIntField, ByteEnumField, StrLenField, XStrField,\
+XStrLenField, XStrFixedLenField, LenField, FieldLenField, PacketField,\
+PacketListField, ConditionalField, PadField
+from scapy.packet import Packet, bind_layers
+from scapy.layers.l2 import SourceMACField, Ether, CookedLinux, GRE, SNAP
+
+
+#
+# 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 = [
+        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:]
+
+    def hashret(self):
+        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)):
+                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, 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),
+        ConditionalField(
+            StrLenField("message", '', length_from=lambda pkt: pkt.len - 5),
+                         lambda pkt: pkt.code == EAP.REQUEST 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
+    INITIATE = 5
+    FINISH = 6
+
+    registered_methods = {}
+
+    @classmethod
+    def register_variant(cls):
+        cls.registered_methods[cls.type.default] = cls
+
+    @classmethod
+    def dispatch_hook(cls, _pkt=None, *args, **kargs):
+        if _pkt:
+            c = ord(_pkt[0])
+            if c in [1, 2] and len(_pkt) >= 5:
+                t = ord(_pkt[4])
+                return cls.registered_methods.get(t, cls)
+        return cls
+
+    def haslayer(self, cls):
+        ret = 0
+        if cls == EAP:
+            for eap_class in EAP.registered_methods.values():
+                if isinstance(self, eap_class):
+                    ret = 1
+                    break
+        elif cls in list(EAP.registered_methods.values()) and isinstance(self, cls):
+            ret = 1
+        return ret
+
+    def getlayer(self, cls, nb=1, _track=None):
+        layer = None
+        if cls == EAP:
+            for eap_class in EAP.registered_methods.values():
+                if isinstance(self, eap_class):
+                    layer = self
+                    break
+        else:
+            layer = Packet.getlayer(self, cls, nb, _track)
+        return layer
+
+    def answers(self, other):
+        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)):
+                    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
+
+
+class EAP_MD5(EAP):
+    """
+    RFC 3748 - "Extensible Authentication Protocol (EAP)"
+    """
+
+    name = "EAP-MD5"
+    fields_desc = [
+        ByteEnumField("code", 1, eap_codes),
+        ByteField("id", 0),
+        FieldLenField("len", None, fmt="H", length_of="optional_name",
+                      adjust=lambda p, x: x + 6 + (p.value_size or 0)),
+        ByteEnumField("type", 4, eap_types),
+        FieldLenField("value_size", None, fmt="B", length_of="value"),
+        XStrLenField("value", '', length_from=lambda p: p.value_size),
+        XStrLenField("optional_name", '', length_from=lambda p: 0 if p.len is None or p.value_size is None else (p.len - p.value_size - 6))
+    ]
+
+
+class EAP_TLS(EAP):
+    """
+    RFC 5216 - "The EAP-TLS Authentication Protocol"
+    """
+
+    name = "EAP-TLS"
+    fields_desc = [
+        ByteEnumField("code", 1, eap_codes),
+        ByteField("id", 0),
+        FieldLenField("len", None, fmt="H", length_of="tls_data",
+                      adjust=lambda p, x: x + 10 if p.L == 1 else x + 6),
+        ByteEnumField("type", 13, eap_types),
+        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),
+        #PacketField("tls_data", None, TLS)
+        XStrLenField('tls_data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L))
+    ]
+
+
+class EAP_FAST(EAP):
+    """
+    RFC 4851 - "The Flexible Authentication via Secure Tunneling
+    Extensible Authentication Protocol Method (EAP-FAST)"
+    """
+
+    name = "EAP-FAST"
+    fields_desc = [
+        ByteEnumField("code", 1, eap_codes),
+        ByteField("id", 0),
+        FieldLenField("len", None, fmt="H", length_of="data",
+                      adjust=lambda p, x: x + 10 if p.L == 1 else x + 6),
+        ByteEnumField("type", 43, eap_types),
+        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),
+        XStrLenField('data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L))
+    ]
+
+
+class LEAP(EAP):
+    """
+    Cisco LEAP (Lightweight EAP)
+    https://freeradius.org/rfc/leap.txt
+    """
+
+    name = "Cisco LEAP"
+    fields_desc = [
+        ByteEnumField("code", 1, eap_codes),
+        ByteField("id", 0),
+        ShortField("len", None),
+        ByteEnumField("type", 17, eap_types),
+        ByteField('version', 1),
+        XByteField('unused', 0),
+        FieldLenField("count", None, "challenge_response", "B", adjust=lambda p, x: len(p.challenge_response)),
+        XStrLenField("challenge_response", "", length_from=lambda p: 0 or p.count),
+        StrLenField("username", "", length_from=lambda p: p.len - (8 + (0 or p.count)))
+    ]
+
+
+#############################################################################
+##### IEEE 802.1X-2010 - MACsec Key Agreement (MKA) protocol
+#############################################################################
+
+#________________________________________________________________________
+#
+# IEEE 802.1X-2010 standard
+# Section 11.11.1
+#________________________________________________________________________
+#
+
+_parameter_set_types = {
+    1:   "Live Peer List",
+    2:   "Potential Peer List",
+    3:   "MACsec SAK Use",
+    4:   "Distributed SAK",
+    5:   "Distributed CAK",
+    6:   "KMD",
+    7:   "Announcement",
+    255: "ICV Indicator"
+}
+
+
+# Used by MKAParamSet::dispatch_hook() to instantiate the appropriate class
+_param_set_cls = {
+    1:   "MKALivePeerListParamSet",
+    2:   "MKAPotentialPeerListParamSet",
+    3:   "MKASAKUseParamSet",
+    4:   "MKADistributedSAKParamSet",
+    255: "MKAICVSet",
+}
+
+
+class MACsecSCI(Packet):
+    """
+    Secure Channel Identifier.
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1AE-2006 standard
+    # Section 9.9
+    #________________________________________________________________________
+    #
+
+    name = "SCI"
+    fields_desc = [
+        SourceMACField("system_identifier"),
+        ShortField("port_identifier", 0)
+    ]
+
+    def extract_padding(self, s):
+        return "", s
+
+
+class MKAParamSet(Packet):
+    """
+    Class from which every parameter set class inherits (except
+    MKABasicParamSet, which has no "Parameter set type" field, and must
+    come first in the list of parameter sets).
+    """
+
+    MACSEC_DEFAULT_ICV_LEN = 16
+    EAPOL_MKA_DEFAULT_KEY_WRAP_LEN = 24
+
+    @classmethod
+    def dispatch_hook(cls, _pkt=None, *args, **kargs):
+        """
+        Returns the right parameter set class.
+        """
+
+        cls = conf.raw_layer
+        if _pkt is not None:
+            ptype = struct.unpack("!B", _pkt[0])[0]
+            return globals().get(_param_set_cls.get(ptype), conf.raw_layer)
+
+        return cls
+
+
+class MKABasicParamSet(Packet):
+    """
+    Basic Parameter Set (802.1X-2010, section 11.11).
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "Basic Parameter Set"
+    fields_desc = [
+        ByteField("mka_version_id", 0),
+        ByteField("key_server_priority", 0),
+        BitField("key_server", 0, 1),
+        BitField("macsec_desired", 0, 1),
+        BitField("macsec_capability", 0, 2),
+        BitField("param_set_body_len", 0, 12),
+        PacketField("SCI", MACsecSCI(), MACsecSCI),
+        XStrFixedLenField("actor_member_id", "", length=12),
+        XIntField("actor_message_number", 0),
+        XIntField("algorithm_agility", 0),
+        PadField(
+            XStrLenField(
+                "cak_name",
+                "",
+                length_from=lambda pkt: (pkt.param_set_body_len - 28)
+            ),
+            4,
+            padwith=b"\x00"
+        )
+    ]
+
+    def extract_padding(self, s):
+        return "", s
+
+
+class MKAPeerListTuple(Packet):
+    """
+    Live / Potential Peer List parameter sets tuples (802.1X-2010, section 11.11).
+    """
+
+    name = "Peer List Tuple"
+    fields_desc = [
+        XStrFixedLenField("member_id", "", length=12),
+        XStrFixedLenField("message_number", "", length=4),
+    ]
+
+
+class MKALivePeerListParamSet(MKAParamSet):
+    """
+    Live Peer List parameter sets (802.1X-2010, section 11.11).
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "Live Peer List Parameter Set"
+    fields_desc = [
+        PadField(
+            ByteEnumField(
+                "param_set_type",
+                1,
+                _parameter_set_types
+            ),
+            2,
+            padwith=b"\x00"
+        ),
+        ShortField("param_set_body_len", 0),
+        PacketListField("member_id_message_num", [], MKAPeerListTuple)
+    ]
+
+
+class MKAPotentialPeerListParamSet(MKAParamSet):
+    """
+    Potential Peer List parameter sets (802.1X-2010, section 11.11).
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "Potential Peer List Parameter Set"
+    fields_desc = [
+        PadField(
+            ByteEnumField(
+                "param_set_type",
+                2,
+                _parameter_set_types
+            ),
+            2,
+            padwith=b"\x00"
+        ),
+        ShortField("param_set_body_len", 0),
+        PacketListField("member_id_message_num", [], MKAPeerListTuple)
+    ]
+
+
+class MKASAKUseParamSet(MKAParamSet):
+    """
+    SAK Use Parameter Set (802.1X-2010, section 11.11).
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "SAK Use Parameter Set"
+    fields_desc = [
+        ByteEnumField("param_set_type", 3, _parameter_set_types),
+        BitField("latest_key_an", 0, 2),
+        BitField("latest_key_tx", 0, 1),
+        BitField("latest_key_rx", 0, 1),
+        BitField("old_key_an", 0, 2),
+        BitField("old_key_tx", 0, 1),
+        BitField("old_key_rx", 0, 1),
+        BitField("plain_tx", 0, 1),
+        BitField("plain_rx", 0, 1),
+        BitField("X", 0, 1),
+        BitField("delay_protect", 0, 1),
+        BitField("param_set_body_len", 0, 12),
+        XStrFixedLenField("latest_key_key_server_member_id", "", length=12),
+        XStrFixedLenField("latest_key_key_number", "", length=4),
+        XStrFixedLenField("latest_key_lowest_acceptable_pn", "", length=4),
+        XStrFixedLenField("old_key_key_server_member_id", "", length=12),
+        XStrFixedLenField("old_key_key_number", "", length=4),
+        XStrFixedLenField("old_key_lowest_acceptable_pn", "", length=4)
+    ]
+
+
+class MKADistributedSAKParamSet(MKAParamSet):
+    """
+    Distributed SAK parameter set (802.1X-2010, section 11.11).
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "Distributed SAK parameter set"
+    fields_desc = [
+        ByteEnumField("param_set_type", 4, _parameter_set_types),
+        BitField("distributed_an", 0, 2),
+        BitField("confidentiality_offset", 0, 2),
+        BitField("unused", 0, 4),
+        ShortField("param_set_body_len", 0),
+        XStrFixedLenField("key_number", "", length=4),
+        ConditionalField(
+            XStrFixedLenField("macsec_cipher_suite", "", length=8),
+            lambda pkt: pkt.param_set_body_len > 28
+        ),
+        XStrFixedLenField(
+            "sak_aes_key_wrap",
+            "",
+            length=MKAParamSet.EAPOL_MKA_DEFAULT_KEY_WRAP_LEN
+        )
+    ]
+
+
+class MKADistributedCAKParamSet(MKAParamSet):
+    """
+    Distributed CAK Parameter Set (802.1X-2010, section 11.11).
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "Distributed CAK parameter set"
+    fields_desc = [
+        PadField(
+            ByteEnumField(
+                "param_set_type",
+                5,
+                _parameter_set_types
+            ),
+            2,
+            padwith=b"\x00"
+        ),
+        ShortField("param_set_body_len", 0),
+        XStrFixedLenField(
+            "cak_aes_key_wrap",
+            "",
+            length=MKAParamSet.EAPOL_MKA_DEFAULT_KEY_WRAP_LEN
+        ),
+        XStrField("cak_key_name", "")
+    ]
+
+
+class MKAICVSet(MKAParamSet):
+    """
+    ICV (802.1X-2010, section 11.11).
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "ICV"
+    fields_desc = [
+        PadField(
+            ByteEnumField(
+                "param_set_type",
+                255,
+                _parameter_set_types
+            ),
+            2,
+            padwith=b"\x00"
+        ),
+        ShortField("param_set_body_len", 0),
+        XStrFixedLenField("icv", "", length=MKAParamSet.MACSEC_DEFAULT_ICV_LEN)
+    ]
+
+
+class MKAParamSetPacketListField(PacketListField):
+    """
+    PacketListField that handles the parameter sets.
+    """
+
+    PARAM_SET_LEN_MASK = 0b0000111111111111
+
+    def m2i(self, pkt, m):
+        return MKAParamSet(m)
+
+    def getfield(self, pkt, s):
+        lst = []
+        remain = s
+
+        while remain:
+            len_bytes = struct.unpack("!H", remain[2:4])[0]
+            param_set_len = self.__class__.PARAM_SET_LEN_MASK & len_bytes
+            current = remain[:4 + param_set_len]
+            remain = remain[4 + param_set_len:]
+            current_packet = self.m2i(pkt, current)
+            lst.append(current_packet)
+
+        return remain, lst
+
+
+class MKAPDU(Packet):
+    """
+    MACsec Key Agreement Protocol Data Unit.
+    """
+
+    #________________________________________________________________________
+    #
+    # IEEE 802.1X-2010 standard
+    # Section 11.11
+    #________________________________________________________________________
+    #
+
+    name = "MKPDU"
+    fields_desc = [
+        PacketField("basic_param_set", "", MKABasicParamSet),
+        MKAParamSetPacketListField("parameter_sets", [], MKAParamSet),
+    ]
+
+    def extract_padding(self, s):
+        return "", s
+
+
+bind_layers( Ether,         EAPOL,         type=34958)
+bind_layers( Ether,         EAPOL,         dst='01:80:c2:00:00:03', type=34958)
+bind_layers( CookedLinux,   EAPOL,         proto=34958)
+bind_layers( GRE,           EAPOL,         proto=34958)
+bind_layers( EAPOL,         EAP,           type=0)
+bind_layers( SNAP,          EAPOL,         code=34958)
+bind_layers( EAPOL,         MKAPDU,        type=5)
+
diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py
index 1ee6517b..32421fae 100644
--- a/scapy/layers/l2.py
+++ b/scapy/layers/l2.py
@@ -1,4 +1,4 @@
-## This file is part of Scapy
+# This file is part of Scapy
 ## See http://www.secdev.org/projects/scapy for more informations
 ## Copyright (C) Philippe Biondi <phil@secdev.org>
 ## This program is published under a GPLv2 license
@@ -273,707 +273,6 @@ 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 = [
-        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:]
-
-    def hashret(self):
-        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)):
-                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, 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),
-        ConditionalField(
-            StrLenField("message", '', length_from=lambda pkt: pkt.len - 5),
-                         lambda pkt: pkt.code == EAP.REQUEST 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
-    INITIATE = 5
-    FINISH = 6
-
-    registered_methods = {}
-
-    @classmethod
-    def register_variant(cls):
-        cls.registered_methods[cls.type.default] = cls
-
-    @classmethod
-    def dispatch_hook(cls, _pkt=None, *args, **kargs):
-        if _pkt:
-            c = ord(_pkt[0])
-            if c in [1, 2] and len(_pkt) >= 5:
-                t = ord(_pkt[4])
-                return cls.registered_methods.get(t, cls)
-        return cls
-
-    def haslayer(self, cls):
-        ret = 0
-        if cls == EAP:
-            for eap_class in EAP.registered_methods.values():
-                if isinstance(self, eap_class):
-                    ret = 1
-                    break
-        elif cls in list(EAP.registered_methods.values()) and isinstance(self, cls):
-            ret = 1
-        return ret
-
-    def getlayer(self, cls, nb=1, _track=None):
-        layer = None
-        if cls == EAP:
-            for eap_class in EAP.registered_methods.values():
-                if isinstance(self, eap_class):
-                    layer = self
-                    break
-        else:
-            layer = Packet.getlayer(self, cls, nb, _track)
-        return layer
-
-    def answers(self, other):
-        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)):
-                    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
-
-
-class EAP_MD5(EAP):
-    """
-    RFC 3748 - "Extensible Authentication Protocol (EAP)"
-    """
-
-    name = "EAP-MD5"
-    fields_desc = [
-        ByteEnumField("code", 1, eap_codes),
-        ByteField("id", 0),
-        FieldLenField("len", None, fmt="H", length_of="optional_name",
-                      adjust=lambda p, x: x + 6 + (p.value_size or 0)),
-        ByteEnumField("type", 4, eap_types),
-        FieldLenField("value_size", None, fmt="B", length_of="value"),
-        XStrLenField("value", '', length_from=lambda p: p.value_size),
-        XStrLenField("optional_name", '', length_from=lambda p: 0 if p.len is None or p.value_size is None else (p.len - p.value_size - 6))
-    ]
-
-
-class EAP_TLS(EAP):
-    """
-    RFC 5216 - "The EAP-TLS Authentication Protocol"
-    """
-
-    name = "EAP-TLS"
-    fields_desc = [
-        ByteEnumField("code", 1, eap_codes),
-        ByteField("id", 0),
-        FieldLenField("len", None, fmt="H", length_of="tls_data",
-                      adjust=lambda p, x: x + 10 if p.L == 1 else x + 6),
-        ByteEnumField("type", 13, eap_types),
-        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),
-        XStrLenField('tls_data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L))
-    ]
-
-
-class EAP_FAST(EAP):
-    """
-    RFC 4851 - "The Flexible Authentication via Secure Tunneling
-    Extensible Authentication Protocol Method (EAP-FAST)"
-    """
-
-    name = "EAP-FAST"
-    fields_desc = [
-        ByteEnumField("code", 1, eap_codes),
-        ByteField("id", 0),
-        FieldLenField("len", None, fmt="H", length_of="data",
-                      adjust=lambda p, x: x + 10 if p.L == 1 else x + 6),
-        ByteEnumField("type", 43, eap_types),
-        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),
-        XStrLenField('data', '', length_from=lambda pkt: 0 if pkt.len is None else pkt.len - (6 + 4 * pkt.L))
-    ]
-
-
-class LEAP(EAP):
-    """
-    Cisco LEAP (Lightweight EAP)
-    https://freeradius.org/rfc/leap.txt
-    """
-
-    name = "Cisco LEAP"
-    fields_desc = [
-        ByteEnumField("code", 1, eap_codes),
-        ByteField("id", 0),
-        ShortField("len", None),
-        ByteEnumField("type", 17, eap_types),
-        ByteField('version', 1),
-        XByteField('unused', 0),
-        FieldLenField("count", None, "challenge_response", "B", adjust=lambda p, x: len(p.challenge_response)),
-        XStrLenField("challenge_response", "", length_from=lambda p: 0 or p.count),
-        StrLenField("username", "", length_from=lambda p: p.len - (8 + (0 or p.count)))
-    ]
-
-
-#############################################################################
-##### IEEE 802.1X-2010 - MACsec Key Agreement (MKA) protocol
-#############################################################################
-
-#________________________________________________________________________
-#
-# IEEE 802.1X-2010 standard
-# Section 11.11.1
-#________________________________________________________________________
-#
-
-_parameter_set_types = {
-    1:   "Live Peer List",
-    2:   "Potential Peer List",
-    3:   "MACsec SAK Use",
-    4:   "Distributed SAK",
-    5:   "Distributed CAK",
-    6:   "KMD",
-    7:   "Announcement",
-    255: "ICV Indicator"
-}
-
-
-# Used by MKAParamSet::dispatch_hook() to instantiate the appropriate class
-_param_set_cls = {
-    1:   "MKALivePeerListParamSet",
-    2:   "MKAPotentialPeerListParamSet",
-    3:   "MKASAKUseParamSet",
-    4:   "MKADistributedSAKParamSet",
-    255: "MKAICVSet",
-}
-
-
-class MACsecSCI(Packet):
-    """
-    Secure Channel Identifier.
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1AE-2006 standard
-    # Section 9.9
-    #________________________________________________________________________
-    #
-
-    name = "SCI"
-    fields_desc = [
-        SourceMACField("system_identifier"),
-        ShortField("port_identifier", 0)
-    ]
-
-    def extract_padding(self, s):
-        return "", s
-
-
-class MKAParamSet(Packet):
-    """
-    Class from which every parameter set class inherits (except
-    MKABasicParamSet, which has no "Parameter set type" field, and must
-    come first in the list of parameter sets).
-    """
-
-    MACSEC_DEFAULT_ICV_LEN = 16
-    EAPOL_MKA_DEFAULT_KEY_WRAP_LEN = 24
-
-    @classmethod
-    def dispatch_hook(cls, _pkt=None, *args, **kargs):
-        """
-        Returns the right parameter set class.
-        """
-
-        cls = conf.raw_layer
-        if _pkt is not None:
-            ptype = struct.unpack("!B", _pkt[0])[0]
-            return globals().get(_param_set_cls.get(ptype), conf.raw_layer)
-
-        return cls
-
-
-class MKABasicParamSet(Packet):
-    """
-    Basic Parameter Set (802.1X-2010, section 11.11).
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "Basic Parameter Set"
-    fields_desc = [
-        ByteField("mka_version_id", 0),
-        ByteField("key_server_priority", 0),
-        BitField("key_server", 0, 1),
-        BitField("macsec_desired", 0, 1),
-        BitField("macsec_capability", 0, 2),
-        BitField("param_set_body_len", 0, 12),
-        PacketField("SCI", MACsecSCI(), MACsecSCI),
-        XStrFixedLenField("actor_member_id", "", length=12),
-        XIntField("actor_message_number", 0),
-        XIntField("algorithm_agility", 0),
-        PadField(
-            XStrLenField(
-                "cak_name",
-                "",
-                length_from=lambda pkt: (pkt.param_set_body_len - 28)
-            ),
-            4,
-            padwith=b"\x00"
-        )
-    ]
-
-    def extract_padding(self, s):
-        return "", s
-
-
-class MKAPeerListTuple(Packet):
-    """
-    Live / Potential Peer List parameter sets tuples (802.1X-2010, section 11.11).
-    """
-
-    name = "Peer List Tuple"
-    fields_desc = [
-        XStrFixedLenField("member_id", "", length=12),
-        XStrFixedLenField("message_number", "", length=4),
-    ]
-
-
-class MKALivePeerListParamSet(MKAParamSet):
-    """
-    Live Peer List parameter sets (802.1X-2010, section 11.11).
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "Live Peer List Parameter Set"
-    fields_desc = [
-        PadField(
-            ByteEnumField(
-                "param_set_type",
-                1,
-                _parameter_set_types
-            ),
-            2,
-            padwith=b"\x00"
-        ),
-        ShortField("param_set_body_len", 0),
-        PacketListField("member_id_message_num", [], MKAPeerListTuple)
-    ]
-
-
-class MKAPotentialPeerListParamSet(MKAParamSet):
-    """
-    Potential Peer List parameter sets (802.1X-2010, section 11.11).
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "Potential Peer List Parameter Set"
-    fields_desc = [
-        PadField(
-            ByteEnumField(
-                "param_set_type",
-                2,
-                _parameter_set_types
-            ),
-            2,
-            padwith=b"\x00"
-        ),
-        ShortField("param_set_body_len", 0),
-        PacketListField("member_id_message_num", [], MKAPeerListTuple)
-    ]
-
-
-class MKASAKUseParamSet(MKAParamSet):
-    """
-    SAK Use Parameter Set (802.1X-2010, section 11.11).
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "SAK Use Parameter Set"
-    fields_desc = [
-        ByteEnumField("param_set_type", 3, _parameter_set_types),
-        BitField("latest_key_an", 0, 2),
-        BitField("latest_key_tx", 0, 1),
-        BitField("latest_key_rx", 0, 1),
-        BitField("old_key_an", 0, 2),
-        BitField("old_key_tx", 0, 1),
-        BitField("old_key_rx", 0, 1),
-        BitField("plain_tx", 0, 1),
-        BitField("plain_rx", 0, 1),
-        BitField("X", 0, 1),
-        BitField("delay_protect", 0, 1),
-        BitField("param_set_body_len", 0, 12),
-        XStrFixedLenField("latest_key_key_server_member_id", "", length=12),
-        XStrFixedLenField("latest_key_key_number", "", length=4),
-        XStrFixedLenField("latest_key_lowest_acceptable_pn", "", length=4),
-        XStrFixedLenField("old_key_key_server_member_id", "", length=12),
-        XStrFixedLenField("old_key_key_number", "", length=4),
-        XStrFixedLenField("old_key_lowest_acceptable_pn", "", length=4)
-    ]
-
-
-class MKADistributedSAKParamSet(MKAParamSet):
-    """
-    Distributed SAK parameter set (802.1X-2010, section 11.11).
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "Distributed SAK parameter set"
-    fields_desc = [
-        ByteEnumField("param_set_type", 4, _parameter_set_types),
-        BitField("distributed_an", 0, 2),
-        BitField("confidentiality_offset", 0, 2),
-        BitField("unused", 0, 4),
-        ShortField("param_set_body_len", 0),
-        XStrFixedLenField("key_number", "", length=4),
-        ConditionalField(
-            XStrFixedLenField("macsec_cipher_suite", "", length=8),
-            lambda pkt: pkt.param_set_body_len > 28
-        ),
-        XStrFixedLenField(
-            "sak_aes_key_wrap",
-            "",
-            length=MKAParamSet.EAPOL_MKA_DEFAULT_KEY_WRAP_LEN
-        )
-    ]
-
-
-class MKADistributedCAKParamSet(MKAParamSet):
-    """
-    Distributed CAK Parameter Set (802.1X-2010, section 11.11).
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "Distributed CAK parameter set"
-    fields_desc = [
-        PadField(
-            ByteEnumField(
-                "param_set_type",
-                5,
-                _parameter_set_types
-            ),
-            2,
-            padwith=b"\x00"
-        ),
-        ShortField("param_set_body_len", 0),
-        XStrFixedLenField(
-            "cak_aes_key_wrap",
-            "",
-            length=MKAParamSet.EAPOL_MKA_DEFAULT_KEY_WRAP_LEN
-        ),
-        XStrField("cak_key_name", "")
-    ]
-
-
-class MKAICVSet(MKAParamSet):
-    """
-    ICV (802.1X-2010, section 11.11).
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "ICV"
-    fields_desc = [
-        PadField(
-            ByteEnumField(
-                "param_set_type",
-                255,
-                _parameter_set_types
-            ),
-            2,
-            padwith=b"\x00"
-        ),
-        ShortField("param_set_body_len", 0),
-        XStrFixedLenField("icv", "", length=MKAParamSet.MACSEC_DEFAULT_ICV_LEN)
-    ]
-
-
-class MKAParamSetPacketListField(PacketListField):
-    """
-    PacketListField that handles the parameter sets.
-    """
-
-    PARAM_SET_LEN_MASK = 0b0000111111111111
-
-    def m2i(self, pkt, m):
-        return MKAParamSet(m)
-
-    def getfield(self, pkt, s):
-        lst = []
-        remain = s
-
-        while remain:
-            len_bytes = struct.unpack("!H", remain[2:4])[0]
-            param_set_len = self.__class__.PARAM_SET_LEN_MASK & len_bytes
-            current = remain[:4 + param_set_len]
-            remain = remain[4 + param_set_len:]
-            current_packet = self.m2i(pkt, current)
-            lst.append(current_packet)
-
-        return remain, lst
-
-
-class MKAPDU(Packet):
-    """
-    MACsec Key Agreement Protocol Data Unit.
-    """
-
-    #________________________________________________________________________
-    #
-    # IEEE 802.1X-2010 standard
-    # Section 11.11
-    #________________________________________________________________________
-    #
-
-    name = "MKPDU"
-    fields_desc = [
-        PacketField("basic_param_set", "", MKABasicParamSet),
-        MKAParamSetPacketListField("parameter_sets", [], MKAParamSet),
-    ]
-
-    def extract_padding(self, s):
-        return "", s
-
-
 class ARP(Packet):
     name = "ARP"
     fields_desc = [ XShortField("hwtype", 0x0001),
@@ -1118,32 +417,25 @@ bind_layers( Dot1AD,        Dot1Q,         type=0x8100)
 bind_layers( Dot1Q,         Dot1AD,        type=0x88a8)
 bind_layers( Ether,         Ether,         type=1)
 bind_layers( Ether,         ARP,           type=2054)
-bind_layers( Ether,         EAPOL,         type=34958)
-bind_layers( Ether,         EAPOL,         dst='01:80:c2:00:00:03', type=34958)
 bind_layers( CookedLinux,   LLC,           proto=122)
 bind_layers( CookedLinux,   Dot1Q,         proto=33024)
 bind_layers( CookedLinux,   Dot1AD,        type=0x88a8)
 bind_layers( CookedLinux,   Ether,         proto=1)
 bind_layers( CookedLinux,   ARP,           proto=2054)
-bind_layers( CookedLinux,   EAPOL,         proto=34958)
 bind_layers( GRE,           LLC,           proto=122)
 bind_layers( GRE,           Dot1Q,         proto=33024)
 bind_layers( GRE,           Dot1AD,        type=0x88a8)
 bind_layers( GRE,           Ether,         proto=0x6558)
 bind_layers( GRE,           ARP,           proto=2054)
-bind_layers( GRE,           EAPOL,         proto=34958)
 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( EAPOL,         MKAPDU,        type=5)
 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)
 bind_layers( SNAP,          Dot1AD,        type=0x88a8)
 bind_layers( SNAP,          Ether,         code=1)
 bind_layers( SNAP,          ARP,           code=2054)
-bind_layers( SNAP,          EAPOL,         code=34958)
 bind_layers( SNAP,          STP,           code=267)
 
 conf.l2types.register(ARPHDR_ETHER, Ether)
diff --git a/scapy/layers/radius.py b/scapy/layers/radius.py
index 1038974e..5b6e0baf 100644
--- a/scapy/layers/radius.py
+++ b/scapy/layers/radius.py
@@ -15,7 +15,7 @@ from scapy.fields import ByteField, ByteEnumField, IntField, StrLenField,\
     XStrLenField, XStrFixedLenField, FieldLenField, PacketField,\
     PacketListField, IPField, MultiEnumField
 from scapy.layers.inet import UDP
-from scapy.layers.l2 import EAP
+from scapy.layers.eap import EAP
 from scapy.config import conf
 from scapy.error import Scapy_Exception
 
-- 
GitLab