1# This file is part of Scapy
2# Scapy is free software: you can redistribute it and/or modify
3# it under the terms of the GNU General Public License as published by
4# the Free Software Foundation, either version 2 of the License, or
5# any later version.
6#
7# Scapy is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU General Public License for more details.
11#
12# You should have received a copy of the GNU General Public License
13# along with Scapy. If not, see <http://www.gnu.org/licenses/>.
14
15# scapy.contrib.description = Link Aggregation Control Protocol (LACP)
16# scapy.contrib.status = loads
17
18from scapy.packet import Packet, bind_layers
19from scapy.fields import ByteField, MACField, ShortField, ByteEnumField, IntField, XStrFixedLenField  # noqa: E501
20from scapy.layers.l2 import Ether
21from scapy.data import ETHER_TYPES
22
23
24ETHER_TYPES[0x8809] = 'SlowProtocol'
25SLOW_SUB_TYPES = {
26    'Unused': 0,
27    'LACP': 1,
28    'Marker Protocol': 2,
29}
30
31
32class SlowProtocol(Packet):
33    name = "SlowProtocol"
34    fields_desc = [ByteEnumField("subtype", 0, SLOW_SUB_TYPES)]
35
36
37bind_layers(Ether, SlowProtocol, type=0x8809, dst='01:80:c2:00:00:02')
38
39
40class LACP(Packet):
41    name = "LACP"
42    deprecated_fields = {
43        "actor_port_numer": ("actor_port_number", "2.4.4"),
44        "partner_port_numer": ("partner_port_number", "2.4.4"),
45        "colletctor_reserved": ("collector_reserved", "2.4.4"),
46    }
47    fields_desc = [
48        ByteField("version", 1),
49        ByteField("actor_type", 1),
50        ByteField("actor_length", 20),
51        ShortField("actor_system_priority", 0),
52        MACField("actor_system", None),
53        ShortField("actor_key", 0),
54        ShortField("actor_port_priority", 0),
55        ShortField("actor_port_number", 0),
56        ByteField("actor_state", 0),
57        XStrFixedLenField("actor_reserved", "", 3),
58        ByteField("partner_type", 2),
59        ByteField("partner_length", 20),
60        ShortField("partner_system_priority", 0),
61        MACField("partner_system", None),
62        ShortField("partner_key", 0),
63        ShortField("partner_port_priority", 0),
64        ShortField("partner_port_number", 0),
65        ByteField("partner_state", 0),
66        XStrFixedLenField("partner_reserved", "", 3),
67        ByteField("collector_type", 3),
68        ByteField("collector_length", 16),
69        ShortField("collector_max_delay", 0),
70        XStrFixedLenField("collector_reserved", "", 12),
71        ByteField("terminator_type", 0),
72        ByteField("terminator_length", 0),
73        XStrFixedLenField("reserved", "", 50),
74    ]
75
76
77bind_layers(SlowProtocol, LACP, subtype=1)
78
79MARKER_TYPES = {
80    'Marker Request': 1,
81    'Marker Response': 2,
82}
83
84
85class MarkerProtocol(Packet):
86    name = "MarkerProtocol"
87    fields_desc = [
88        ByteField("version", 1),
89        ByteEnumField("marker_type", 1, MARKER_TYPES),
90        ByteField("marker_length", 16),
91        ShortField("requester_port", 0),
92        MACField("requester_system", None),
93        IntField("requester_transaction_id", 0),
94        XStrFixedLenField("marker_reserved", "", 2),
95        ByteField("terminator_type", 0),
96        ByteField("terminator_length", 0),
97        XStrFixedLenField("reserved", 0, 90),
98    ]
99
100
101bind_layers(SlowProtocol, MarkerProtocol, subtype=2)
102