2 * Routines for Link Aggregation Control Protocol dissection.
3 * IEEE Std 802.1AX-2014 Section 6.4.2.3
4 * Split from IEEE Std 802.3-2005 and named IEEE 802.3ad before that
6 * Copyright 2002 Steve Housley <steve_housley@3com.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <epan/etypes.h>
18 #include <epan/packet.h>
19 #include <epan/to_str.h>
20 #include <epan/expert.h>
21 #include <epan/slow_protocol_subtypes.h>
23 #include <wsutil/array.h>
25 /* General declarations */
26 void proto_register_lacp(void);
27 void proto_reg_handoff_lacp(void);
29 static dissector_handle_t lacp_handle
;
31 #define VLACP_MAGIC_LACP 0x01010114
32 #define VLACP_MAGIC_MARKER 0x02010114
35 #define LACPDU_TYPE_TERMINATOR 0x00
36 #define LACPDU_TYPE_ACTOR_INFORMATION 0x01
37 #define LACPDU_TYPE_PARTNER_INFORMATION 0x02
38 #define LACPDU_TYPE_COLLECTOR_INFORMATION 0x03
40 static const value_string lacp_type_vals
[] = {
41 { LACPDU_TYPE_TERMINATOR
, "Terminator" },
42 { LACPDU_TYPE_ACTOR_INFORMATION
, "Actor Information" },
43 { LACPDU_TYPE_PARTNER_INFORMATION
, "Partner Information" },
44 { LACPDU_TYPE_COLLECTOR_INFORMATION
, "Collector Information" },
48 /* Actor and Partner Flag bits */
49 #define LACPDU_FLAGS_ACTIVITY 0x01
50 #define LACPDU_FLAGS_TIMEOUT 0x02
51 #define LACPDU_FLAGS_AGGREGATION 0x04
52 #define LACPDU_FLAGS_SYNC 0x08
53 #define LACPDU_FLAGS_COLLECTING 0x10
54 #define LACPDU_FLAGS_DISTRIB 0x20
55 #define LACPDU_FLAGS_DEFAULTED 0x40
56 #define LACPDU_FLAGS_EXPIRED 0x80
58 /* Initialise the protocol and registered fields */
59 static int proto_lacp
;
61 static int hf_lacp_vlacp_subtype
;
62 static int hf_lacp_version
;
63 static int hf_lacp_tlv_type
;
64 static int hf_lacp_tlv_length
;
66 static int hf_lacp_actor_sysid_priority
;
67 static int hf_lacp_actor_sysid
;
68 static int hf_lacp_actor_key
;
69 static int hf_lacp_actor_port_priority
;
70 static int hf_lacp_actor_port
;
71 static int hf_lacp_actor_state
;
72 static int hf_lacp_actor_state_str
;
73 static int hf_lacp_flags_a_activity
;
74 static int hf_lacp_flags_a_timeout
;
75 static int hf_lacp_flags_a_aggregation
;
76 static int hf_lacp_flags_a_sync
;
77 static int hf_lacp_flags_a_collecting
;
78 static int hf_lacp_flags_a_distrib
;
79 static int hf_lacp_flags_a_defaulted
;
80 static int hf_lacp_flags_a_expired
;
81 static int hf_lacp_actor_reserved
;
83 static int hf_lacp_partner_sysid_priority
;
84 static int hf_lacp_partner_sysid
;
85 static int hf_lacp_partner_key
;
86 static int hf_lacp_partner_port_priority
;
87 static int hf_lacp_partner_port
;
88 static int hf_lacp_partner_state
;
89 static int hf_lacp_partner_state_str
;
90 static int hf_lacp_flags_p_activity
;
91 static int hf_lacp_flags_p_timeout
;
92 static int hf_lacp_flags_p_aggregation
;
93 static int hf_lacp_flags_p_sync
;
94 static int hf_lacp_flags_p_collecting
;
95 static int hf_lacp_flags_p_distrib
;
96 static int hf_lacp_flags_p_defaulted
;
97 static int hf_lacp_flags_p_expired
;
98 static int hf_lacp_partner_reserved
;
100 static int hf_lacp_coll_max_delay
;
101 static int hf_lacp_coll_reserved
;
103 static int hf_lacp_pad
;
105 static int hf_lacp_vendor
;
107 static int hf_lacp_vendor_hp_length
;
108 static int hf_lacp_vendor_hp_irf_domain
;
109 static int hf_lacp_vendor_hp_irf_mac
;
110 static int hf_lacp_vendor_hp_irf_switch
;
111 static int hf_lacp_vendor_hp_irf_port
;
112 static int hf_lacp_vendor_hp_unknown
;
115 /* Initialise the subtree pointers */
117 static int ett_lacp_a_flags
;
118 static int ett_lacp_p_flags
;
121 static expert_field ei_lacp_wrong_tlv_type
;
122 static expert_field ei_lacp_wrong_tlv_length
;
124 static const true_false_string tfs_active_passive
= { "Active", "Passive" };
125 static const true_false_string tfs_short_long_timeout
= { "Short Timeout", "Long Timeout" };
126 static const true_false_string tfs_aggregatable_individual
= { "Aggregatable", "Individual" };
127 static const true_false_string tfs_in_sync_out_sync
= { "In Sync", "Out of Sync" };
129 static const char * lacp_state_flags_to_str(wmem_allocator_t
*scope
, uint32_t value
)
131 wmem_strbuf_t
*buf
= wmem_strbuf_new(scope
, "");
132 const unsigned int flags_count
= 8;
133 static const char first_letters
[] = "EFDCSGSA";
136 for (i
= 0; i
< flags_count
; i
++) {
137 if (((value
>> (flags_count
- 1 - i
)) & 1)) {
138 wmem_strbuf_append_c(buf
, first_letters
[i
]);
140 wmem_strbuf_append_c(buf
, '*');
144 return wmem_strbuf_finalize(buf
);
151 * This function is used to dissect the Link Aggregation Control Protocol
152 * defined in IEEE 802.1AX
155 * tvb: buffer associated with the rcv packet (see tvbuff.h).
156 * pinfo: structure associated with the rcv packet (see packet_info.h).
157 * tree: the protocol tree associated with the rcv packet (see proto.h).
159 * Return Values: None
164 dissect_lacp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
166 int offset
= 0, length_remaining
;
167 unsigned tlv_type
, tlv_length
;
168 unsigned version
, port
, key
;
169 const char *sysidstr
, *flagstr
;
170 uint32_t protodetect
;
173 proto_tree
*lacp_tree
;
174 proto_item
*lacp_item
, *tlv_type_item
, *tlv_length_item
;
177 static int * const actor_flags
[] = {
178 &hf_lacp_flags_a_activity
,
179 &hf_lacp_flags_a_timeout
,
180 &hf_lacp_flags_a_aggregation
,
181 &hf_lacp_flags_a_sync
,
182 &hf_lacp_flags_a_collecting
,
183 &hf_lacp_flags_a_distrib
,
184 &hf_lacp_flags_a_defaulted
,
185 &hf_lacp_flags_a_expired
,
188 static int * const partner_flags
[] = {
189 &hf_lacp_flags_p_activity
,
190 &hf_lacp_flags_p_timeout
,
191 &hf_lacp_flags_p_aggregation
,
192 &hf_lacp_flags_p_sync
,
193 &hf_lacp_flags_p_collecting
,
194 &hf_lacp_flags_p_distrib
,
195 &hf_lacp_flags_p_defaulted
,
196 &hf_lacp_flags_p_expired
,
200 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "LACP");
201 col_set_str(pinfo
->cinfo
, COL_INFO
, "Link Aggregation Control Protocol");
204 * Validate that the destination MAC address is one of the following
205 * (IEEE 802.1AX-2014 6.2.11.2):
206 * 01-80-C2-00-00-00: Nearest Customer Bridge group address
207 * 01-80-C2-00-00-02: IEEE 802.3 Slow_Protocols_Mulitcast group address
208 * 01-80-C2-00-00-03: Nearest non-TPMR Bridge group address
211 protodetect
= tvb_get_ntohl(tvb
, 0);
212 if ((protodetect
== VLACP_MAGIC_LACP
) || (protodetect
== VLACP_MAGIC_MARKER
)) {
214 /* Add vLACP Heading */
215 lacp_item
= proto_tree_add_protocol_format(tree
, proto_lacp
, tvb
,
216 0, -1, "Virtual Link Aggregation Control Protocol");
219 /* Add LACP Heading - Note: 1 byte for slowprotocol has been consumed already */
220 lacp_item
= proto_tree_add_protocol_format(tree
, proto_lacp
, tvb
,
221 0, -1, "Link Aggregation Control Protocol");
223 lacp_tree
= proto_item_add_subtree(lacp_item
, ett_lacp
);
226 proto_tree_add_item(lacp_tree
, hf_lacp_vlacp_subtype
, tvb
, offset
, 1, ENC_NA
);
232 proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_version
, tvb
, offset
, 1, ENC_NA
, &version
);
235 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "v%d", version
);
239 tlv_type_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_type
);
242 tlv_length_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_length
);
245 if (tlv_type
!= LACPDU_TYPE_ACTOR_INFORMATION
) {
246 expert_add_info(pinfo
, tlv_type_item
, &ei_lacp_wrong_tlv_type
);
248 if (tlv_length
!= 20) {
249 expert_add_info(pinfo
, tlv_length_item
, &ei_lacp_wrong_tlv_length
);
252 proto_tree_add_item(lacp_tree
, hf_lacp_actor_sysid_priority
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
255 proto_tree_add_item(lacp_tree
, hf_lacp_actor_sysid
, tvb
, offset
, 6, ENC_NA
);
256 sysidstr
= tvb_ether_to_str(pinfo
->pool
, tvb
, offset
);
259 proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_actor_key
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &key
);
262 proto_tree_add_item(lacp_tree
, hf_lacp_actor_port_priority
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
265 proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_actor_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &port
);
268 proto_tree_add_bitmask_with_flags(lacp_tree
, tvb
, offset
, hf_lacp_actor_state
,
269 ett_lacp_a_flags
, actor_flags
, ENC_NA
, BMT_NO_INT
|BMT_NO_TFS
|BMT_NO_FALSE
);
270 flagstr
= lacp_state_flags_to_str(pinfo
->pool
, tvb_get_uint8(tvb
, offset
));
271 ti
= proto_tree_add_string(lacp_tree
, hf_lacp_actor_state_str
, tvb
, offset
, 1, flagstr
);
272 proto_item_set_generated(ti
);
275 proto_tree_add_item(lacp_tree
, hf_lacp_actor_reserved
, tvb
, offset
, 3, ENC_NA
);
278 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " ACTOR %s P: %d K: %d %s", sysidstr
, port
, key
, flagstr
);
282 tlv_type_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_type
);
285 tlv_length_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_length
);
288 if (tlv_type
!= LACPDU_TYPE_PARTNER_INFORMATION
) {
289 expert_add_info(pinfo
, tlv_type_item
, &ei_lacp_wrong_tlv_type
);
291 if (tlv_length
!= 20) {
292 expert_add_info(pinfo
, tlv_length_item
, &ei_lacp_wrong_tlv_length
);
295 proto_tree_add_item(lacp_tree
, hf_lacp_partner_sysid_priority
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
298 proto_tree_add_item(lacp_tree
, hf_lacp_partner_sysid
, tvb
, offset
, 6, ENC_NA
);
299 sysidstr
= tvb_ether_to_str(pinfo
->pool
, tvb
, offset
);
302 proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_partner_key
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &key
);
305 proto_tree_add_item(lacp_tree
, hf_lacp_partner_port_priority
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
308 proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_partner_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &port
);
311 proto_tree_add_bitmask_with_flags(lacp_tree
, tvb
, offset
, hf_lacp_partner_state
, ett_lacp_p_flags
, partner_flags
, ENC_NA
, BMT_NO_INT
|BMT_NO_TFS
|BMT_NO_FALSE
);
312 flagstr
= lacp_state_flags_to_str(pinfo
->pool
, tvb_get_uint8(tvb
, offset
));
313 ti
= proto_tree_add_string(lacp_tree
, hf_lacp_partner_state_str
, tvb
, offset
, 1, flagstr
);
314 proto_item_set_generated(ti
);
317 proto_tree_add_item(lacp_tree
, hf_lacp_partner_reserved
, tvb
, offset
, 3, ENC_NA
);
320 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " PARTNER %s P: %d K: %d %s", sysidstr
, port
, key
, flagstr
);
324 tlv_type_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_type
);
327 tlv_length_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_length
);
330 if (tlv_type
!= LACPDU_TYPE_COLLECTOR_INFORMATION
) {
331 expert_add_info(pinfo
, tlv_type_item
, &ei_lacp_wrong_tlv_type
);
333 if (tlv_length
!= 16) {
334 expert_add_info(pinfo
, tlv_length_item
, &ei_lacp_wrong_tlv_length
);
337 proto_tree_add_item(lacp_tree
, hf_lacp_coll_max_delay
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
340 proto_tree_add_item(lacp_tree
, hf_lacp_coll_reserved
, tvb
, offset
, 12, ENC_NA
);
343 /* col_append_fstr(pinfo->cinfo, COL_INFO, " COLLECTOR"); */
345 /* Other TLVs (LACP version 2) */
347 proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_type
);
350 tlv_length_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_length
);
353 while (tlv_type
!= LACPDU_TYPE_TERMINATOR
&& tlv_length
>= 2) {
354 offset
+= (tlv_length
- 2);
355 proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_type
);
358 tlv_length_item
= proto_tree_add_item_ret_uint(lacp_tree
, hf_lacp_tlv_length
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &tlv_length
);
362 /* Terminator - already handled */
364 if (tlv_length
!= 0) {
365 expert_add_info(pinfo
, tlv_length_item
, &ei_lacp_wrong_tlv_length
);
370 if (offset
< (128 - 1 - 18)) { /* LACPv1 fixed size - Eth */
371 proto_tree_add_item(lacp_tree
, hf_lacp_pad
, tvb
, offset
, (128 - 1 - 18)-offset
, ENC_NA
);
372 offset
+= ((128 - 1 - 18)-offset
);
375 /* HP specific stuff (in violation of standard) */
377 length_remaining
= tvb_reported_length_remaining(tvb
, offset
);
378 if (length_remaining
) {
380 /* HP LACP MAD IRF, first bytes is always 0x64 and second bytes is the rest of length */
381 if (length_remaining
> 2 && (tvb_get_uint8(tvb
, offset
) == 0x64) && ((length_remaining
-2) == tvb_get_uint8(tvb
, offset
+1)) )
383 proto_tree_add_item(lacp_tree
, hf_lacp_vendor
, tvb
, offset
, length_remaining
, ENC_NA
);
384 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_unknown
, tvb
, offset
, 1, ENC_NA
);
387 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_length
, tvb
, offset
, 1, ENC_NA
);
390 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_unknown
, tvb
, offset
, 2, ENC_NA
);
393 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_irf_domain
, tvb
, offset
, 2, ENC_NA
);
396 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_irf_mac
, tvb
, offset
, 6, ENC_NA
);
399 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_unknown
, tvb
, offset
, 8, ENC_NA
);
402 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_irf_switch
, tvb
, offset
, 2, ENC_NA
);
405 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_irf_port
, tvb
, offset
, 2, ENC_NA
);
408 proto_tree_add_item(lacp_tree
, hf_lacp_vendor_hp_unknown
, tvb
, offset
, 2, ENC_NA
);
410 /* Not the HP specific extras. Don't claim the remaining data. It may actually be an ethernet trailer. */
411 set_actual_length(tvb
, tvb_captured_length(tvb
) - length_remaining
);
412 proto_item_set_len(lacp_item
, tvb_captured_length(tvb
));
415 return tvb_captured_length(tvb
);
418 /* Register the protocol with Wireshark */
420 proto_register_lacp(void)
422 /* Setup list of header fields */
424 static hf_register_info hf
[] = {
425 { &hf_lacp_vlacp_subtype
,
426 { "vLACP subtype", "lacp.vlacp_subtype",
427 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
428 "Avaya vlacp unused lacp subtype byte", HFILL
}},
431 { "LACP Version", "lacp.version",
432 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
436 { "TLV Type", "lacp.tlv_type",
437 FT_UINT8
, BASE_HEX
, VALS(lacp_type_vals
), 0x0,
440 { &hf_lacp_tlv_length
,
441 { "TLV Length", "lacp.tlv_length",
442 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
445 { &hf_lacp_actor_sysid_priority
,
446 { "Actor System Priority", "lacp.actor.sys_priority",
447 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
450 { &hf_lacp_actor_sysid
,
451 { "Actor System ID", "lacp.actor.sysid",
452 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
455 { &hf_lacp_actor_key
,
456 { "Actor Key", "lacp.actor.key",
457 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
460 { &hf_lacp_actor_port_priority
,
461 { "Actor Port Priority", "lacp.actor.port_priority",
462 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
465 { &hf_lacp_actor_port
,
466 { "Actor Port", "lacp.actor.port",
467 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
470 { &hf_lacp_actor_state
,
471 { "Actor State", "lacp.actor.state",
472 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
475 { &hf_lacp_actor_state_str
,
476 { "Actor State Flags", "lacp.actor.state_str",
477 FT_STRING
, BASE_NONE
, NULL
, 0x0,
480 { &hf_lacp_flags_a_activity
,
481 { "LACP Activity", "lacp.actor.state.activity",
482 FT_BOOLEAN
, 8, TFS(&tfs_active_passive
), LACPDU_FLAGS_ACTIVITY
,
485 { &hf_lacp_flags_a_timeout
,
486 { "LACP Timeout", "lacp.actor.state.timeout",
487 FT_BOOLEAN
, 8, TFS(&tfs_short_long_timeout
), LACPDU_FLAGS_TIMEOUT
,
490 { &hf_lacp_flags_a_aggregation
,
491 { "Aggregation", "lacp.actor.state.aggregation",
492 FT_BOOLEAN
, 8, TFS(&tfs_aggregatable_individual
), LACPDU_FLAGS_AGGREGATION
,
495 { &hf_lacp_flags_a_sync
,
496 { "Synchronization", "lacp.actor.state.synchronization",
497 FT_BOOLEAN
, 8, TFS(&tfs_in_sync_out_sync
), LACPDU_FLAGS_SYNC
,
500 { &hf_lacp_flags_a_collecting
,
501 { "Collecting", "lacp.actor.state.collecting",
502 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), LACPDU_FLAGS_COLLECTING
,
505 { &hf_lacp_flags_a_distrib
,
506 { "Distributing", "lacp.actor.state.distributing",
507 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), LACPDU_FLAGS_DISTRIB
,
510 { &hf_lacp_flags_a_defaulted
,
511 { "Defaulted", "lacp.actor.state.defaulted",
512 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), LACPDU_FLAGS_DEFAULTED
,
513 "1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL
}},
515 { &hf_lacp_flags_a_expired
,
516 { "Expired", "lacp.actor.state.expired",
517 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), LACPDU_FLAGS_EXPIRED
,
520 { &hf_lacp_actor_reserved
,
521 { "Reserved", "lacp.actor.reserved",
522 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
525 { &hf_lacp_partner_sysid_priority
,
526 { "Partner System Priority", "lacp.partner.sys_priority",
527 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
530 { &hf_lacp_partner_sysid
,
531 { "Partner System", "lacp.partner.sysid",
532 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
535 { &hf_lacp_partner_key
,
536 { "Partner Key", "lacp.partner.key",
537 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
540 { &hf_lacp_partner_port_priority
,
541 { "Partner Port Priority", "lacp.partner.port_priority",
542 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
545 { &hf_lacp_partner_port
,
546 { "Partner Port", "lacp.partner.port",
547 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
548 "The port number associated with this link assigned to the port by the Partner (via Management or Admin)", HFILL
}},
550 { &hf_lacp_partner_state
,
551 { "Partner State", "lacp.partner.state",
552 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
555 { &hf_lacp_partner_state_str
,
556 { "Partner State Flags", "lacp.partner.state_str",
557 FT_STRING
, BASE_NONE
, NULL
, 0x0,
560 { &hf_lacp_flags_p_activity
,
561 { "LACP Activity", "lacp.partner.state.activity",
562 FT_BOOLEAN
, 8, TFS(&tfs_active_passive
), LACPDU_FLAGS_ACTIVITY
,
565 { &hf_lacp_flags_p_timeout
,
566 { "LACP Timeout", "lacp.partner.state.timeout",
567 FT_BOOLEAN
, 8, TFS(&tfs_short_long_timeout
), LACPDU_FLAGS_TIMEOUT
,
570 { &hf_lacp_flags_p_aggregation
,
571 { "Aggregation", "lacp.partner.state.aggregation",
572 FT_BOOLEAN
, 8, TFS(&tfs_aggregatable_individual
), LACPDU_FLAGS_AGGREGATION
,
575 { &hf_lacp_flags_p_sync
,
576 { "Synchronization", "lacp.partner.state.synchronization",
577 FT_BOOLEAN
, 8, TFS(&tfs_in_sync_out_sync
), LACPDU_FLAGS_SYNC
,
580 { &hf_lacp_flags_p_collecting
,
581 { "Collecting", "lacp.partner.state.collecting",
582 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), LACPDU_FLAGS_COLLECTING
,
585 { &hf_lacp_flags_p_distrib
,
586 { "Distributing", "lacp.partner.state.distributing",
587 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), LACPDU_FLAGS_DISTRIB
,
590 { &hf_lacp_flags_p_defaulted
,
591 { "Defaulted", "lacp.partner.state.defaulted",
592 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), LACPDU_FLAGS_DEFAULTED
,
593 "1 = Actor Rx machine is using DEFAULT Partner info, 0 = using info in Rx'd LACPDU", HFILL
}},
595 { &hf_lacp_flags_p_expired
,
596 { "Expired", "lacp.partner.state.expired",
597 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), LACPDU_FLAGS_EXPIRED
,
600 { &hf_lacp_partner_reserved
,
601 { "Reserved", "lacp.partner.reserved",
602 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
605 { &hf_lacp_coll_max_delay
,
606 { "Collector Max Delay", "lacp.collector.max_delay",
607 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
608 "The max delay of the station sending the LACPDU (in tens of usecs)", HFILL
}},
610 { &hf_lacp_coll_reserved
,
611 { "Reserved", "lacp.coll_reserved",
612 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
617 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
621 { "Unknown vendor", "lacp.vendor",
622 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
623 "Some extra bytes (Vendor Specific ?)", HFILL
}},
625 /* HP IRF MAD LACP */
626 { &hf_lacp_vendor_hp_length
,
627 { "Length", "lacp.vendor.hp.length",
628 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
629 "The length of HP TLV", HFILL
}},
630 { &hf_lacp_vendor_hp_irf_domain
,
631 { "IRF Domain", "lacp.vendor.hp.irf_domain",
632 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
634 { &hf_lacp_vendor_hp_irf_mac
,
635 { "IRF MAC", "lacp.vendor.hp.irf_mac",
636 FT_ETHER
, BASE_NONE
, NULL
, 0x0,
638 { &hf_lacp_vendor_hp_irf_switch
,
639 { "IRF Switch", "lacp.vendor.hp.irf_switch",
640 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
641 "Number of switch on the IRF stack", HFILL
}},
642 { &hf_lacp_vendor_hp_irf_port
,
643 { "IRF Port", "lacp.vendor.hp.irf_port",
644 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
645 "Stack ID where the LACP is attached", HFILL
}},
646 { &hf_lacp_vendor_hp_unknown
,
647 { "Unknown", "lacp.vendor.hp.unknown",
648 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
652 /* Setup protocol subtree array */
654 static int *ett
[] = {
660 static ei_register_info ei
[] = {
661 { &ei_lacp_wrong_tlv_type
, { "lacp.wrong_tlv_type", PI_MALFORMED
, PI_ERROR
, "TLV is not expected type", EXPFILL
}},
662 { &ei_lacp_wrong_tlv_length
, { "lacp.wrong_tlv_length", PI_MALFORMED
, PI_ERROR
, "TLV is not expected length", EXPFILL
}},
665 expert_module_t
* expert_lacp
;
668 /* Register the protocol name and description */
670 proto_lacp
= proto_register_protocol("Link Aggregation Control Protocol", "LACP", "lacp");
672 /* Required function calls to register the header fields and subtrees used */
674 proto_register_field_array(proto_lacp
, hf
, array_length(hf
));
675 proto_register_subtree_array(ett
, array_length(ett
));
676 expert_lacp
= expert_register_protocol(proto_lacp
);
677 expert_register_field_array(expert_lacp
, ei
, array_length(ei
));
679 lacp_handle
= register_dissector("lacp", dissect_lacp
, proto_lacp
);
683 proto_reg_handoff_lacp(void)
685 dissector_add_uint("slow.subtype", LACP_SUBTYPE
, lacp_handle
);
686 dissector_add_uint("ethertype", ETHERTYPE_VLACP
, lacp_handle
);
690 * Editor modelines - https://www.wireshark.org/tools/modelines.html
695 * indent-tabs-mode: nil
698 * vi: set shiftwidth=4 tabstop=8 expandtab:
699 * :indentSize=4:tabSize=8:noTabs=true: